PHPでのマルチバイト文字扱いの学習で半日使ってしまった。
PHPというのは今現在内部に保持している文字のコードは統一されているわけではなくて、そのときにフォームで送られた文字コードやファイルで読み込んだ文字コードそのままで保持されている。
$_POST[]や$_GET[]で受け取った文字コードは自動変換してもらうこともでき、それはphp.iniや.htaccessなどで設定する。
それをちょっと書いてみる。
1.変換の有無
mbstring.encoding_translation
まずこれが最初。自動変換のスイッチ。
これがonだと変換してくれる。
2.どのコードに変換するのかは、
mbstring.internal_encoding
の設定値。UTF-8とかEUC-JPとか。
これはmb系関数での変換元コードにもなる。
例えばmb_send_mail()だと、ここで指定したコードからmbstring.languageの指定した「言語」に変換してメール送信する。
ただ、mbstring.languageではコード指定はできないので、"Japanese"が指定されていても何に変換されるかは規定されていないらしい(?)。普通はISO-2022-JPだろうけど。
気をつけないといけないのは、この設定はPHP内部コードを何にするかではなくて、文字列のコード種を何として扱うかという前提を定めているだけ。だから実際のコード種が何になっているかは受け取ったソースによるわけだ。
3.変換元のコード種が何かを指定するのが
mbstring.http_input
ここでUTF-8とか直に指定するのもいいし、autoで自動判別してもらうこともできる。
autoの場合、検査順は「ASCII,JIS,UTF-8,EUC-JP,SJIS」
直値を複数並べて自分で検査順を指定することもできる。"UTF-8,EUC-JP,SJIS,JIS,ASCII"的に。
順番によって判別の誤りに多い少ないがあるとか。誤判別されるともちろん後はどうにもならない。
passで変換無し。
例えば、ここで送られた文字列のコードがUTF-8と検知されたら、その文字列のコードをUTF-8として、bstring.internal_encodingで指定したコード種に自動変換してくれる。
よくある文字化けする要因としては、
例えばWebページから受け取ったコードがSJISなのに、mbstring.internal_encodingをEUC-JPにしてて、
mb_mail_send()を使用すると、内部でSJISをEUC-JPだと思ってISO-2022-JPに変換してしまい意味の無いコードになってしまうとかそういうことだろう。
このときのブラウザ表示に関してはContent-Typeが適用されるから、送られたコードと表示コードが一致するから問題無し。
もちろん上記の自動変換したときはWeb側と内部コードが食い違うから表示も文字化けする。表示するときに変換が必要になる。
ファイルから読み込んだ文字列についてはmb_convert_encoding()などで変換してやればいい。
最低限このぐらい知っていればいいんじゃないかと。
つまり、PHPは今内部にある文字列のコード種は何かをいつも意識していないといけないわけだな。
webページのContent-Typeとmbstring.internal_encodingのコード種をそろえておけば、こういった心配はいらなくなる。
プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB .../矢野 啓介

¥2,709
Amazon.co.jp
PHP 逆引きレシピ (PROGRAMMER’S RECiPE)/鈴木 憲治

¥2,730
Amazon.co.jp
PHPというのは今現在内部に保持している文字のコードは統一されているわけではなくて、そのときにフォームで送られた文字コードやファイルで読み込んだ文字コードそのままで保持されている。
$_POST[]や$_GET[]で受け取った文字コードは自動変換してもらうこともでき、それはphp.iniや.htaccessなどで設定する。
それをちょっと書いてみる。
1.変換の有無
mbstring.encoding_translation
まずこれが最初。自動変換のスイッチ。
これがonだと変換してくれる。
2.どのコードに変換するのかは、
mbstring.internal_encoding
の設定値。UTF-8とかEUC-JPとか。
これはmb系関数での変換元コードにもなる。
例えばmb_send_mail()だと、ここで指定したコードからmbstring.languageの指定した「言語」に変換してメール送信する。
ただ、mbstring.languageではコード指定はできないので、"Japanese"が指定されていても何に変換されるかは規定されていないらしい(?)。普通はISO-2022-JPだろうけど。
気をつけないといけないのは、この設定はPHP内部コードを何にするかではなくて、文字列のコード種を何として扱うかという前提を定めているだけ。だから実際のコード種が何になっているかは受け取ったソースによるわけだ。
3.変換元のコード種が何かを指定するのが
mbstring.http_input
ここでUTF-8とか直に指定するのもいいし、autoで自動判別してもらうこともできる。
autoの場合、検査順は「ASCII,JIS,UTF-8,EUC-JP,SJIS」
直値を複数並べて自分で検査順を指定することもできる。"UTF-8,EUC-JP,SJIS,JIS,ASCII"的に。
順番によって判別の誤りに多い少ないがあるとか。誤判別されるともちろん後はどうにもならない。
passで変換無し。
例えば、ここで送られた文字列のコードがUTF-8と検知されたら、その文字列のコードをUTF-8として、bstring.internal_encodingで指定したコード種に自動変換してくれる。
よくある文字化けする要因としては、
例えばWebページから受け取ったコードがSJISなのに、mbstring.internal_encodingをEUC-JPにしてて、
mb_mail_send()を使用すると、内部でSJISをEUC-JPだと思ってISO-2022-JPに変換してしまい意味の無いコードになってしまうとかそういうことだろう。
このときのブラウザ表示に関してはContent-Typeが適用されるから、送られたコードと表示コードが一致するから問題無し。
もちろん上記の自動変換したときはWeb側と内部コードが食い違うから表示も文字化けする。表示するときに変換が必要になる。
ファイルから読み込んだ文字列についてはmb_convert_encoding()などで変換してやればいい。
最低限このぐらい知っていればいいんじゃないかと。
つまり、PHPは今内部にある文字列のコード種は何かをいつも意識していないといけないわけだな。
webページのContent-Typeとmbstring.internal_encodingのコード種をそろえておけば、こういった心配はいらなくなる。
プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB .../矢野 啓介

¥2,709
Amazon.co.jp
PHP 逆引きレシピ (PROGRAMMER’S RECiPE)/鈴木 憲治

¥2,730
Amazon.co.jp