以前にPHPではURLデコードまで自動的にやってくれるということを書いて、その後は処理するときの文字コードに変換など施してめちゃめちゃ食べやすい状態にしておくみたいなことをコードも交えてちらほら書いてきました。
が、少々小汚いコードだったことと、あの後にmb_convert_variables()関数という便利なのがあることを知って「SJIS-win」「CP51932」のような文字コード指定方法があることも知ったので今一度ここに書き直しておきます。
デコードその後の処理という意味でdecplus()という関数名にしました。
引数を渡さないと日本語EUCにするように書いたので以下では「SJIS-win」を渡してシフトJISにする処理で書いています。
[URLデコードその後]
decplus("SJIS-win");
function decplus($tojcode="CP51932")
{
$fromjcode= "SJIS-win,UTF-8,CP51932,JIS";
$fromtonl= array("\x0d\x0a"=>"\n", "\x0a"=>"\n", "\x0d"=>"\n");
// binaryがあれば削って、改行コードを環境のものに統一して、前後ブランク文字があればトリミング
function _decplus(&$array, $fromtonl){
foreach ($array as $key=>&$value){
if (is_array($value)) _decplus($value, $fromtonl);
else $array[$key]= trim(strtr(preg_replace('/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f\xff]/', "", $value), $fromtonl));
}
}
mb_convert_variables($tojcode, $fromjcode, $_POST,$_REQUEST,$_GET,$_COOKIE);
_decplus($_POST, $fromtonl);
_decplus($_REQUEST, $fromtonl);
_decplus($_GET, $fromtonl);
_decplus($_COOKIE, $fromtonl);
}
?>
まずPHPスクリプトが受け取った時点での文字コードは未知であり私の場合はページ表示をシフトJISで行うので同じシフトJISで送信されてくる確率が高くなるため先頭に「SJIS-win」を書いています。
それと、シフトJISの半角カナのみだと日本語EUCと誤判定されるので必ず日本語EUCを表す「CP51932」より先に書くというのもあります。
幸いにもmb_convert_variables()関数は値を内部で連結させて、より高い精度での文字コード判定を行うようになっているようです。
decplus()関数内に_decplus()関数を書いていますがこれを呼び出して「バイナリコード」があれば削除して、改行コードを環境のものに統一させて、前後にブランク文字(空白)があれば取り除く処理を施しています。
フォームデータ値やクッキー値は配列でセットされている場合も考えられるので引数を参照渡しにして配列なら再帰処理にしています。
これと併せてforeachループでもリファレンスを使うことで引数に渡された配列そのものを変換するようにしています。これはPHP5からできるようになってるらしいです。
strtr()関数に渡す改行コード変換用配列は、このように一度に処理させることで先頭に書いた"\x0d\x0a"(CRLF)があればこれで優先的に処理するのでこの順番で書いています。
ちょっと過剰な処理になってしまったのでPOSTとGETに対応させてバイナリ除去・トリミングは不要なら以下のように書いてスッキリさせてもいいかと。
[URLデコードその後2]
decplus("SJIS-win");
function decplus($tojcode="CP51932")
{
$fromjcode= "SJIS-win,UTF-8,CP51932,JIS";
$fromtonl= array("\x0d\x0a"=>"\n", "\x0a"=>"\n", "\x0d"=>"\n");
// 前後ブランク文字があればトリミング
function _decplus(&$array, $fromtonl){
foreach ($array as $key=>&$value){
if (is_array($value)) _decplus($value, $fromtonl);
else $array[$key]= strtr($value, $fromtonl);
}
}
mb_convert_variables($tojcode, $fromjcode, $_POST,$_GET);
_decplus($_POST, $fromtonl);
_decplus($_GET, $fromtonl);
}
?>
