文字化けとの戦い2008-06-05
多少なりともプログラムを書く日本人なら、文字化けに悩まされた事が無い人はいないでしょう。サーバ、データベース、そしてプログラム言語などの環境が変わると、大抵問題が発生します。
昨日も、新しいレンタルサーバ(試用期間)で、僕の掲示板などが動くかどうか試したのですが、やっぱり見事に文字化けしていました。
そこでとりあえず、PHPの初期設定で文字コードをUTF8(今回はこれで統一)しておこう。と言っても、レンタルサーバなのでphp.iniは弄れないので:
php_value mbstring.language neutral
php_value mbstring.internal_encoding UTF-8
php_value mbstring.http_output UTF-8
php_value default_charset UTF-8
php_value mbstring.encoding_translation off
とかなんとか、htaccessに書いて埋め込みます。しかしダメ、相変わらず?マークだらけの文字化けです。
やっぱり奴のせいか・・・そう、あの悪名高きMySQL4.1以降の文字コード自動変換機能のことです。初期設定ファイルなどで幾ら文字コードを設定しても、何を血迷ったかMySQLが勝手に変更してしまうという、あの不可解かつ迷惑な機能の仕業に違いない。(ちなみに現行サーバはMySQL3なので文字化けは起こりません)
こういう場合にとても便利なのは、
mysql_query(“SET NAMES utf8”);
と言う呪文。これをPHPアプリに埋め込むと・・・見事!一発で文字化けが直りました。
”SET NAMES (文字コード)”を使ってはいけないですと?
ところがネットで検索していると、どうやらこの”SET NAMES …”を使うのはセキュリティー上マズイらしい。この話の大本を辿っていくと、PHP界では有名な大垣靖男氏のブログに突き当たりました。
先ずこのブログ自体が、Firefoxでみると文字化けしてしまうのが何とも不可解ですが、非常に荒っぽくまとめると次のような事のようです。
- アプリケーション上で、SQL文を使ってデータベースの文字コードを設定してはいけない。
- やるなら文字エンコーディング設定するAPIを利用すべき。
- PHPなら”mysql_set_charset()“という関数を使うと良い。しかし!これはPHP5.2.3以降しかサポートしていない。
つまり、MySQL4.1以降かつPHP5.2.2以前の環境では対策を考える必要があると。
ただ、EUC-JPかUTF-8でコーディングする場合は:
この場合は話は簡単で入力時点で文字列がEUC-JPまたはUTF-8で正しくエンコーディングされているかチェックするだけです。アプリケーションの入力チェック処理としてmb_check_encoding(無い場合はmb_convert_encoding)を利用して文字エンコーディングが正しいかチェックすれば大丈夫です。そのまま、mysql_escape_stringを使ってエスケープすればほとんどの環境で大丈夫だと思います。
だそうです。頑張ります・・・しかし、セキュリティーって本当にややこしいですね。素人じゃ脆弱性だらけ・・・フレームワークを使っても万全とは言い切れない。
また、こういう話になると、PHPやSQLのバージョンを自由に選べないレンタル(共用)サーバって、制約がきついなと感じます。ホスティング会社としては、 ヘタにバージョンアップすると様々なユーザーの現行アプリケーションが正常に作動しないかもしれないので、昔のままで固定してしまう。しかし、言語のバージョンが古いと脆弱性が残っているし、最新のツール(WordpressやZenCart)も動作しないのです。