page_adsence

2011年4月26日火曜日

機種依存文字の文字コード変換

今回やっている案件で、CSV内に記述されているマルチバイトの文字をaddslashesでエスケープしている処理があった。
しかし、文字コードがSJISだったために、5C問題に該当する部分のSQLは全て失敗していた。
なので、その改修を今回行うために調べた内容を残す。

まずaddslashesについて調べてみた。
addslashesはマルチバイトに対応してないのに、普通に使われていてビビった。
とはいえ、全くエスケープされないわけではないので、
深く調べずにやると今回のような現象が起こる。

で、mysql_real_escape_stringを使うのが普通なのだが、
この関数も結局マルチバイトに対応しているわけではないので、


CSVに記述されているSJISの機種依存文字をMysqlのDBに入れようとした際のログ。
要件としては、機種依存文字や5C文字を安全にエスケープする方法を探す。

機種依存文字は基本的にはSJISには存在してない。
なので
mb_convert_encoding($text, 'utf-8', 'sjis');
などをしようものなら、あっという間に?とかに文字化けてしまう。
なので、

$str = mb_convert_encoding(mb_convert_encoding($text, 'sjis-win', 'sjis'), 'UTF-8', 'sjis-win');

上記のように一度sjisからsjis-winにエンコードしてから、UTF-8にエンコードをする。
こうすることで機種依存文字を文字化けさせることなく、文字コードを変換できる。

で、UTF-8に変換することで、5C問題は解決されるので、ここでエスケープする。

$str = mysql_real_escape_string($str);

で、エスケープした文字列を再びsjisに戻す。

$str = mb_convert_encoding($str, 'sjis-win', 'UTF-8');

ここで注意しないといけないのは、元のsjisに戻してしまうと、機種依存文字が文字化けしてしまうこと。
sjisには機種依存文字が存在しないので、戻す時はsjis-winに戻さないと、正常に表示できない。

とりあえず今回調べた感じだとこんな感じ。
なんか最初っからsjis-winからutf-8で変換できんじゃねって思ってやってみたらいけたし!!
まぁ試した文字はあんまりいっぱい試してないので、もしかしたら駄目な場合もあるのかも。
でも理論的には問題無さそうな気がする。
というわけで、最終的にはこんな感じで。

$str = mb_convert_encoding($text, 'UTF-8', 'sjis-win');
$str = mysql_real_escape_string($str);
$str = mb_convert_encoding($str, 'sjis-win', 'UTF-8');

MySQLでFLUSH PRIVILEGESを使うとエラーが出る

CentOSに入っているMySQLでFLUSH PRIVILEGESを実行したところ、

ERROR 1146 (42S02): Table ‘mysql.servers’ doesn’t exist

とでた。
ググってみるとmysqlのDB内のserversというテーブルがないってエラーでした。
消した記憶ないのに、こんな現象になっているのは腑に落ちないんですけど、
とりあえず以下のSQLを流してみたら問題無かった。

CREATE TABLE `servers` (
 `Server_name` char(64) NOT NULL,
 `Host` char(64) NOT NULL,
 `Db` char(64) NOT NULL,
 `Username` char(64) NOT NULL,
 `Password` char(64) NOT NULL,
 `Port` int(4) DEFAULT NULL,
 `Socket` char(64) DEFAULT NULL,
 `Wrapper` char(64) NOT NULL,
 `Owner` char(64) NOT NULL,
 PRIMARY KEY (`Server_name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='MySQL Foreign Servers table';


何でこのテーブル無くなったんだろう…。
間違えて消したのかな。。。

2011年4月25日月曜日

svnで衝突を解消するためのコマンド

なんか最近svnを使う機会が減ってきたのでメモ。

hoge.phpというファイルが衝突した場合の解消手順

1.衝突したファイルを開いて、衝突マーカの部分を修正し、保存。
$ vi hoge.php
<<<<<<< .mine
aaaa
bbbb
=======
bbbb
cccc
>>>>>>> .r2
.mimeとなっている部分はローカルで修正を加えたもの。
.rXXXとなっている部分はリビジョンXXXで修正が加えられたもの。

正しくマージして保存した後に、該当のファイルに対して解消のコマンドを打つ。
svn resolved hoge.php

MySQLでユーザーの追加や権限等の設定

毎回忘れてググっているので、忘れてもいいようにメモ。

ユーザーの追加には以下のようなSQLを流す。
mysql> GRANT <操作名> ON <データベース名>.<テーブル名> TO <ユーザ名>@<ホスト名> IDENTIFIED BY '<パスワード>';
mysql> FLUSH PRIVILEGES;

操作名は下記にある表の中から選んで使用する。
セキュリティを全く考慮しないのであれば、ALLでも問題はない。
データベース名やテーブル名を指定することで、指定したデータベースやテーブル以外にはアクセスできないようなユーザーを作成することができる。
ユーザー名はDBに接続する際に使用するユーザー名
接続先のDBがあるホスト名またはIPを記載する。
WebサーバとDBサーバが一緒であれば、localhostで繋がる。
WebサーバとDBサーバが異なる場合は、DBサーバのホスト名またはIPを記載することで接続できる。
「FLUSH PRIVILEGES」はユーザー情報の反映のためのSQLで、これをしないと作成したユーザーで
ログインすることはできない。


操作名一覧
ALL
  すべての権限を設定出来るユーザを追加
ALTER
  ALTER TABLE(テーブル変更)の使用を許可
CREATE
  CREATE TABLE(テーブル作成) の使用を許可
CREATE TEMPORARY TABLES
  CREATE TEMPORARY TABLE(一時テーブルの作成) の使用を許可
DROP
  DROP TABLE(テーブルの削除) の使用を許可
INDEX
  CREATE INDEX(インデックス作成) および DROP INDEX(インデックス削除) の使用を許可
LOCK TABLES
  SELECT 権限を持つテーブルで LOCK TABLES(テーブルのロック) の使用を許可
PROCESS
  SHOW FULL PROCESSLIST の使用を許可
REPLICATION CLIENT
  スレーブおよびマスタのサーバーを知る権利を付与
REPLICATION SLAVE
  レプリケーションのスレーブに必要(マスタからバイナリログを読み取るため)
SHOW DATABASES
  SHOW DATABASES によりすべてのデータベースが表示される
SHUTDOWN
  mysqladmin shutdown の使用を許可

2011年4月17日日曜日

2010-2011シーズンまとめ

去年は北海道に篭っていたので、東京からの通いでゲレンデに行くのは1年ぶり。
車で10分でゲレンデに着くってのもいいけど、
2~3時間かけて車でゲレンデに行く途中の感じも捨てがたいですねー。
篭っていた前のシーズンに比べると、今年は大分行ったなー。
今シーズンのシーズンインは12月29日にかぐらにて。
ちょっと遅めのシーズンインだったので、今年もそんなにいけないかなーと思っていましたけど、
以外に行ってました。
回数的には6回と少な目ですが、うち泊まりが3回あったおかげで、滑走日数としては9日間となりました。
ただ、地震の影響もあり、結局3月5日に行った南郷スキー場がすべり収めになってしまいました・・・。

今シーズン行ったゲレンデレポ
・かぐらスキー場(2010/12/29)
まぁシーズンインでしたし、ゲレンデの状態もそこそこでした。
昼過ぎ位からちらほら雪が降ってきてちょっとはコンディションが上がったかな程度です。
ちょっと時間が経つとすぐにアイスバーンが見えるとこが何箇所かありました。
ただ、まだ他のゲレンデが空いていないこの時期に、ものすごく人が少なかったので、
リフト待ちとかなくて楽だったなぁー。
初めて一緒に滑るメンバーだったので、それはそれで楽しかったですけど、
よくいくゲレンデだし、特にコレといった感想はないですね。

・かぐらスキー場(2011/1/29)
かぐら2連続。
神立行く予定だったのですが、急遽かぐらへ変更になりました。
結構雪降ってて、パウダーが楽しめました。
行きなれているかぐらですが、パウダーにありつける機会はなかなかないので、
楽しかったですねー。
また、初めて一緒に行く人とかもいてさらに楽しさアップな感じでした。
ただ、やっぱかぐらは平らだなーって思いました。
ゲレンデ的にはいまいちな感じを再実感。

・野沢温泉スキー場(2011/2/5~2011/2/6)
今シーズン初の泊まりイベント。
野沢温泉はDVDで見てから行きたくてしょうがなかったゲレンデだったので、
ものすごく楽しみにしてました。
その期待を裏切らないめっちゃ面白いゲレンデでした!!
どのコースにも結構な数のポコジャンがあって、
サイズは小さいですけど、かなり楽しめます!
さらに頂上から左右にコースが分かれるんですが、
そこの真ん中が最高に楽しい!!!
谷みたいな感じになってて、ちょっとしたハーフパイプ気分が味わえます!
でもそこそこ雪あるので、めっちゃ疲れます・・・。
ゲレンデ合流ちょっと前くらいにいい感じのサイズのポコジャンがあって、そこも楽しめました。
このコースに行くまでのリフトの乗り継ぎは微妙ですが、
行く価値アリのゲレンデでした。

・パルコール嬬恋(2011/2/11~2011/2/12)
今シーズン2回目の泊まりイベント。
ゲレンデ自体は行ったことのあるゲレンデだったし、
行ったときにめっちゃ吹雪いてた思い出が強くてあまり楽しいイメージはありませんでした。
また、インター降りてからも雪が全然なくて大丈夫かって思ってましたけど、
ゲレンデに着くころにはちらほら降り出してきていい感じに。
コース脇を楽しむって感じではないですが、コンディションがよかったので楽しめました。
また、泊まったホテルもよかったし、一緒に行った面子もよかったので最高に楽しかった!
やっぱ場所ってそれほど重要じゃないっすねー。

・上越国際スキー場(2011/2/19~2011/2/20)
3週連続の泊まりイベントのラスト。
初日の朝はコンディションが最高によくって、パウダーだらけ!
しかも山の向こう側に移動したら人がいないいない。
がっつりパウダーを僕らで頂いちゃいました。
ただ、ゲレンデ間の移動はかなりきついですね・・・。
1本滑るまでに40分くらいゲレンデを移動してました。
本当にリフトの乗り継ぎが悪い悪い・・・。
ゴンドラもないので、山頂に行くのにも結構な時間がかかります。
それさえなければ結構よかったんですが・・・。
コース脇の傾斜とかはそんなでもなかったですが、
所々にポコジャンがあって、1回めっちゃ高さの出たジャンプができたので最高に気持ちよかったです。
また行きたいかといわれると、コンディション次第では行ってもいいかなぁ~って感じですね。
やっぱリフトでの乗り継ぎが悪いのは結構致命的です。

・南郷スキー場(2011/3/5)
結局これが今シーズンラストランになってしまいました・・・。
今シーズンよく一緒に行っている人が南郷いいよって話を聞いていて、
ずっと僕の中で行ってみたいと思っていたゲレンデでした。
が、福島県でしかもインターを降りてから80km以上とめっさ遠いんです。
下道だけで大体2時間くらい・・・。
でも、それだけの価値のあるゲレンデでした。
滑り始める前まで雪ががっつり降っていたので、パウダーを散々頂いた後に、
いい感じのポコジャンもあって最高に楽しかったです。
南郷スキー場は間違いなく今シーズンNo1のゲレンデでした!
ぜひ来シーズンも行きたいですねー。

2011年4月12日火曜日

pear upgradeでのエラーその2

pearでupgradeしようと思ったら再びエラーが。

WARNING: channel "pear.php.net" has updated its protocols, use "channel-update pear.php.net" to update
Cannot install, php_dir for channel "pear.php.net" is not writeable by the current user

pearのチャンネルが古いらしい。

# pear channel-update pear.php.net

と実行する。

pear/PEAR dependency package "pear/Console_Getopt" downloaded version 1.3.1 is not the recommended version 1.2.3, but may be compatible, use --force to install
pear/Archive_Tar requires PEAR Installer (version >= 1.5.4), installed version is 1.4.9
pear/Console_Getopt requires PEAR Installer (version >= 1.8.0), installed version is 1.4.9
No valid packages found
upgrade failed

PEARとArchive_Tar及びConsole_Getoptとのバージョンの兼ね合いで、upgradeできないみたい。

なので、Archive_TarとConsole_Getoptを強制的にアップデートする。

# pear upgrade --force Archive_Tar
# pear upgrade --force Console_Getopt

で、完了後に

# pear upgrade pear

あと、pearでインストール時にパーミッションが足りないと下記のようなメッセージがでるんだ。
初めて知った。
ぶっちゃけわかりずらい…。
PHP Fatal error:  Call to undefined method PEAR::raiseerro() in /usr/share/pear/PEAR/REST.php on line 165

2011年4月6日水曜日

scpの通信ログをログファイルに残す方法

cronに登録してあるシェルスクリプト内でscpで通信していて、
その通信ログをログファイルに残そうと思って、リダイレクトしてみたんですが、
ログファイル自体は問題無く生成されたんですが、中身が一向に書き出されない。
で、原因を調べてみたら同じ問題にぶち当たってる人が知恵袋で聞いてました。


scpコマンドでのファイル転送結果を、ログ出力する方法を教えてください。


コマンドとしてはこんな感じらしい。
以下の場合は別サーバからファイルを受信する時のログをa.logにリダイレクトさせるってもの。
知恵袋の回答ではlocalhostをノンパスログインできる状態にしてからやるって書いてあったけど、
とりあえずパスワードありでもログが出せるかどうかの検証だけはできたので、試してみた。

ssh -t -q -A localhost scp user@server:送信元ファイル名 送信先ディレクトリ 1>>a.log


ちなみに指定されているsshのオプションを解説すると、
tオプションは仮想端末を割り当てるためのオプション。
qオプションは警告メッセージ・診断メッセージを抑制するためのオプション。
Aオプションは認証エージェントの転送を許可するためのオプション。

一応上記の方法でログは書きこまれるようになりました。
しかし、scpのログを残すだけでこんなに作業しないといけないとは…。
面倒くさいなぁ~。

sshコマンドのオプションについて

sshコマンドのオプションについて調べてみた。
実はデフォルトのマニュアルに載ってないオプションが結構たくさんあってビビる。
意味がよくわかってない部分もありますが、とりあえず記載しておく。

オプション名 説明
-1 SSHのバージョン1を使用します。
-2 SSHのバージョン2を使用します。
-4 IPv4を指定します。
-6 IPv6を指定します。
-A 認証エージェントの転送を許可します。
-a 認証エージェントの転送を禁止します。
-b IPアドレス 複数のIPアドレスをもつ場合、バインドするIPアドレスを指定します。
-C データを圧縮します。
-c 暗号方式 暗号方式を指定します。
  • 3des(トリプルdes方式)
  • blowfish(ブロック暗号方式)
  • des(des方式)
-D [IPアドレス:]ポート番号 転送に使用するポート番号を指定します。
-e エスケープ文字 エスケープ文字を指定します。
-F ファイル名 設定ファイルを指定します。
-f バックグラウンドで実行します。
-g ホストが転送されたローカルなポートに接続することを許可します。
-I デバイス名 スマートカードのデバイスを指定します。
-i ファイル名 RSA認証 / DSA認証の際に秘密鍵を読むファイルを指定します。
-k GSSAPI証明書をホストに転送することを禁止します。
-L[クライアントIPアドレス:]ポート番号:ホストIPアドレス:ポート番号 クライアント→ホストのポート転送の際のアドレス・ポートを指定します。
-l ログイン名 ログイン名を指定します。
-M 接続を共有する為のmasterモードに設定します。
-m メッセージ認証コード MAC(メッセージ認証コード)を指定します。
  • hmac-md5
  • hmac-sha1
  • umac-64@openssh.com
  • hmac-ripemd160
  • hmac-sha1-96
  • hmac-md5-96
-N リモートコマンドを無効にします。
-n 標準入力からの読み込みを禁止します。
-O コマンド 制御コマンドを実行します。
chesk
マスタープロセスが走っているかのチェックを行います。
exit
マスタープロセスに終了を指示します。
-o オプション 設定ファイルと同じ形式でオプションを指定します。
-p ポート番号 ホストに接続するポートを指定します。
-q 警告メッセージ・診断メッセージを抑制します。
-R [クライアントIPアドレス:]ポート番号:ホスト:ポート番号 ホスト→クライアントのポート転送を行います。
-S ソケットのパス 制御を共有する際に制御用ソケットのパスを設定します。
-s ホスト側でサブシステムの実行を行います。
-T 仮想端末の割り当てを禁止します。
-t 仮想端末を割り当てる。
-V バージョンを表示します。
-v 進行中のデバッグメッセージの表示を行います。
-w クライアント側のトンネルデバイス,[:ホストのトンネルデバイス] トンネリングするクライアントのデバイスとホストのデバイスを設定します。
-X X11 の転送を許可します。
-x X11 の転送を禁止します。
-Y 信頼されたX11転送を許可します。

vimで文字コードを修正する

よく使うけど、結構忘れるのでメモ。

vimでファイルを開いたりするとファイルが文字化けしている場合がある。
こういった場合には、ファイルの文字コードを指定して開きなおす必要がある。
まず開いたファイルの文字コードを変更して読み込む方法は以下の通り。
:e ++enc=文字コード
例)
:e ++enc=utf-8


ファイルの文字コードを指定して保存する方法は以下の通り。
:set fileencoding=utf-8

2011年4月4日月曜日

CSSで上下に中央寄せする方法

ここに書かれていた。
書き方としては以下の通り。
IE6と7以外に関してはtable-cellを使う。
IE6と7に関してはインライン要素として扱うと、「vertical-align」が使えるようになるので、下記のような記述になっている。
ちなみに下記に書かれている「* html」はIE6用のハックで、「*:first-child+html」はIE7用のハックである。
これを記述した場合にはそれぞれのブラウザでしか反映しないに出来る。

div {
    display:table-cell;
    margin-bottom:1px;
    vertical-align:middle;
}

/* IE 6 hack */
* html div {
    display:inline;
    zoom:1;
}

/* IE 7 hack */
*:first-child+html div {
    display:inline;
    zoom:1;
}

2011年4月1日金曜日

IE6でfirst-childとlast-childを使うには

IE6でfirst-childやlast-childを使いたい場合には以下のようにする。
例)背景色を変えたい場合
* html div {
    background-color: expression((this.parentNode.firstChild == this) ? '#FFB6C1': '#DADADA';
}

ちなみに同じ要素に対して、first-childとlast-childを使いたい場合は以下のようにする。
* html div {
    background-color: expression((this.parentNode.firstChild == this) ? '#FFB6C1' : (this.parentNode.lastChild == this) ? '#ADD8E6' : '#DADADA');
}

とこういった感じでやる。
ちなみに上記はIE6のみに適用するように記述してある。
expressionとかをいっぱいやりすぎるとサイト全体が重くなるので要注意。
ただでさえJavascriptの処理が遅いIE6で連発するのは危険。
どうしようもない場合にこれを使う位の感じで使った方がよい。

ついでに調べていたらexpressionはやたらめったら評価されてしまうので、
one-time expressionを使いましょうって記事がありました。
以下が例です。(時間によって適用される背景色が変わるようになっているみたいです。)
<style>
P {
    background-color: expression(altBgcolor(this));
}
</style>
<script>
function altBgcolor(elem) {
    elem.style.backgroundColor = (new Date()).getHours()%2 ? "#F08A00" : "#B8D4FF";
}
</script>

expressionが設定されているスタイルを上書きするようになってるみたいです。
確かにこれなら一度評価された時点で上書きされてしまうので、
何度も評価される事態を回避できます。
これならある程度の数を使っても大丈夫そうです。