phpの設定で、デフォルトでは「Off」になっている、「mbstring.encoding_translation」。
マニュアルには、
入力される HTTP クエリに関して、 文字エンコーディング検出および内部文字エンコーディングへの変換を行う 透過的な文字エンコーディングフィルタを有効にします。
と、いかにも便利っぽいことが書いてあるけど、まあだいたいの場面において、『自動的に』という処理は罠であることが多い。
DBはUTF-8、スクリプトもUTF-8で、サイトのHTMLがShift-JISという、少し特殊な環境のシステムでの改訂作業でのこと。
このシステムが稼働するサーバーは、内部文字エンコードがEUC-JPになっていた。
最近では珍しいけれど、DBの文字コードとそれを処理・表現するスクリプトの文字コードに齟齬がなければ、基本的に文字化けが起こることはない。HTMLがShift-JISであっても、出力時にShift-JISにコンバートしてやればいいだけだ。内部エンコードの設定はそのままでも全然大丈夫、、、のはず。。。
ところが、このシステムが稼働するサーバーのphp.iniの「mbstring.encoding_translation」がONになっていた。
この場合、内部エンコードがEUC-JPなので、送信されたデータはすべてEUC-JPにコンバートされてしまう。
うぜぇ・・・
PHPには、スクリプト上で文字エンコードの設定を行う関数がいろいろと用意されていて、内部文字エンコードも、スクリプト上で変更することが可能だけども、このencoding_translationというやつ、設定可能箇所が「PHP_INI_PERDIR」なので、スクリプト上での変更ができない。
それじゃあ、ということで、mb_internal_encoding()関数で、内部エンコードをUTF-8にしてみたが、全然効き目がない。
どうやら、スクリプトで設定が変更される前に、「mbstring.endocing_translation」によってPOST(またはGET)されたデータのコンバート処理が行われてしまうらしい。
うぜぇぞ・・・
当のサーバーはといえば、php.iniの設定変更はもちろんのこと、.htaccessによる変更も許可されていないので、「mbstring.encoding_translation」の設定を変更する手段がない。
こうなるともう、POSTデータとGETデータを片っ端からコンバートするしかない・・・
$system_encoding = 'UTF-8';
$encoding_translation = ini_get('mbstring.encoding_translation');
$internal_encoding = ini_get('mbstring.internal_encoding');
$aryData = GetRequestData(); //
foreach($aryData as $qkey => $qval)
{
if( $encoding_translation == 1 ){
$qval = mb_convert_encoding($qval, $system_encoding, $internal_encoding);
}
$$qkey = $qval;
}
このレンタルサーバー、システムはEUC-JPで作りなさい、といってるようなもんだ。
内部エンコードがEUC-JPなのはいい。一昔前に借りたサーバーはだいたいDBも内部エンコードもEUCだし。
でも「mbstring.encoding_translation=On」はよろしくない。スクリプトでハンドリングできない項目で、それを変更する手段を提供してないくせによぉ。。。
あー、愚痴った愚痴った。