携帯向けのサイトを作るのであれば、出力する文字コードは事実上Shift_JISしか選択肢がない。だがPostgreSQL(などRDB)も、PHPやテンプレートなどスクリプトファイルも、Shift_JISよりはEUC_JPのほうが都合がいい。

で、ずいぶん古いがこんな不具合がある。

【PostgreSQLウォッチ】第27回 SQLインジェクション脆弱性を修正,日本語ユーザーに大きな影響:ITpro

ので、データベース接続にclient encodingを指定しての自動変換も使いたくない(というか事実上使っちゃダメ)。

ということで、マルチバイト文字の流れとエンコーディングは以下のようにしている。

[SJIS] - クライアント
     ↓ 
[SJIS] - PHP (フィルタでSJIS->EUC変換)
     ↓
[EUC]  - PostgreSQL (store)
     ↓
[EUC]  - PostgreSQL (select)
     ↓
[EUC]  - PHP (mb_output_handlerがEUC->SJIS変換)
     ↓ 
[SJIS] - クライアント

php.iniの設定は以下のようになる。

output_buffering = On
output_handler = mb_output_handler
mbstring.language = Japanese
mbstring.internal_encoding = EUCJP-win
mbstring.http_input = pass
mbstring.http_output = SJIS-win
mbstring.encoding_translation = Off
mbstring.detect_order = auto

mbstring.http_inputはpassにしておくと入力がそのままPHPに渡るので、フィルタで料理してやる。autoを指定すると一見便利っぽいが、文字コードの自動判別は往々にしてしくじることがあるのでアテにしないほうがいいだろう。

なお、

mbstring.http_input = SJIS-win
mbstring.encoding_translation = On

にしておくと、入力を自動的に変換してくれる模様。kwappaでは他のコンテキストでもアプリが動いているサーバで開発していたので、ここでは設定せずフィルタで変換する方式にした。この辺は好みと環境でいいのではないだろうか。…厳密な検証はしてないのだが。

 

携帯なので入出力に絵文字が混じるため、SJIS,EUC-JPではなくSJIS-win,EUCJP-winを指定する。絵文字は機種依存文字(外字)エリアのコードを使うらしいのでこの設定が必要になる模様。

私が担当する以前はPHP内部がSJISだった(client encodingを使用していた)ため、既存の絵文字関連ルーチンはすべてSJIS用に作られている。そのため絵文字処理のEUC版を実装しなくてはならなくなった。近い将来行うので、形になったらエントリしようと思う。