2012年2月28日火曜日

ServersMan@VPS(Debian32bit)のphpで日本語が消える

昔他のサーバで動かしていたphpの自作ウェブアプリケーションを
ServersMan@VPS(Debian32bit)で動かそうとしたところ問題が発生しました。
しょうがないので解析していくと、
escapeshellcmd()を通した前後で
ブラウザから入力したシフトJISの日本語文字列というかバイト列のうち、
MSBが1のバイトが消えていることがわかりました。
そりゃまともに動かないって。

7ビットのASCIIキャラクタしか残っていないとなると
文字コード関連くさいことは予想できるので、
ネットで探していると似たような症状に出会った方が結構いるようで、
そこでの解決方法も参考にしつつ
コードの最初のほうに
setlocale(LC_ALL,"ja_JP.SJIS");
を追加してみました。
つまりロケールの問題だということです。
実際
echo setlocale(LC_ALL,"0");
の実行結果は"C"だったのでさもありなんと。

ところが改善がみられません。
確認してみると、ロケールを設定したにもかかわらず
"C"から全く変更できていないのです。
しょうがないので"/etc"ディレクトリでロケール関連のファイルを探すと
"/etc/locale.gen"設定ファイルがあり、
この中を見て、ロケールが片っ端からコメントアウトされていることに気付きました。
このファイルの先頭にコメントがあって、
システムがサポートするロケールは
"/usr/share/i18n/SUPPORTED"ファイルに書いてあるということですが、
なんと"ja_JP.SJIS"がない…
この時点でシフトJISはあきらめてUTF-8を使うことを決断しました。
まあHTML5の世界ではUTF-8を使うべきでしょうし。

で、"/etc/locale.gen"で
ja_JP.EUC-JP EUC-JP
ja_JP.UTF-8 UTF-8
の2つのロケールのコメントアウトを外し、
# locale-gen
を実行してEUCとUTF-8が使えるようにしました。
必要ないかもしれませんが、私はここでリブートしました。

ウェブアプリケーションの方は
setlocale(LC_ALL,"ja_JP.SJIS");

setlocale(LC_ALL,"ja_JP.UTF-8");
に変更し、"encoding"や"charset"等の設定を
"Shift_JIS"から"UTF-8"に変更し、
日本語のリテラル文字列を片っ端からUTF-8に直して
きちんと動作することが確認できました。

まったくもう、手間かけさせやがって。
私の中でシフトJISは完全廃止にしようかと。

0 件のコメント:

コメントを投稿