関連:PHP/tips/推奨php.ini設定
日本語環境php.ini設定 †
日本語環境でPHPを利用する場合に推奨するphp.ini設定です。php.iniで指定しなくても良い物は関数で設定しても良いと思います。特にポータブルなスクリプトはini設定をスクリプト中で行うか、設定変更しなけれならない物(magic_quote_gpc等)はスクリプト中でチェックすると良いと思います。
マルチバイト文字モジュールとしてiconvモジュールもありますが、実用的なアプリケーションではmbstringモジュールを使用します。
特に重要なのはセキュリティ上の理由からPHPが入力文字エンコーディングを自動的に変換しないようにする事です。
UTF-8またはEUC-JP環境 †
EUC-JP環境の場合、UTF-8をEUC-JPまたはEUC-JP-winに読み替えてください。
データベース、スクリプトを記述するファイルの文字エンコーディングはPHPの文字エンコーディングを使用する方が設定が行い易いです。
default_charset="UTF-8" †
ダイナミックコンテンツの文字コードセットは必ず指定しなければならない。(セキュリティ上の理由。詳細は2000年2月のCERTのXSSアドバイザリを参照)
magic_quotes_gpc=off †
マルチバイト文字エンコーディング環境のみでなく、セキュリティ上も有害であるので必ずoffに設定する。ポータブルなスクリプトの場合、この設定がonである場合にstrip_slashes()を全ての入力に適用するコードをスクリプトの開始時に実行する。稀にmagic_quote_gpc=onである事を前提としているアプリケーションもある。そのようなアプリケーションは使わない方が良い。
mbstring.input_encoding="pass" †
現在のブラウザでHTMLを記述した文字エンコーディング以外で文字を送信してくるようなブラウザはない。(携帯などモバイル環境を除く)
mbstring.internal_encoding="UTF-8" †
ブラウザから送信される文字エンコーディングはcharsetと同じはず。プログラム側では必ず送信された文字エンコーディングが正当なUTF-8エンコーディングであるか確認する事。
mbstring.output_encoding="pass" †
出力はinternal_encodingで行われる。つまりUTF-8。(携帯などモバイル環境を除く)
mbstring.language="japanese" †
言語環境を日本語に設定。mb_send_mail関数などの動作に影響する。
mbstring.substitute_charactor="" †
入力に変換出来ない文字エンコーディングを含む場合、アプリケーションの実行を停止しなければならない。本来、セキュリティ上不正な文字を削除すべきではないが、古いPHP(PHP 4.4.2, 5.1.2以下)では文字エンコーディングを確認する仕組みが無い。古いPHPで効率的に不正エンコーディングを検出するには文字列の長さの変化で確認する。*1
PHP 5.1.3, 4.3.3以降はmb_check_encoding関数を利用してスクリプトを実行の初期段階で不正エンコーディングを検出することが望ましい。
SJIS環境 †
SJIS環境の場合、HTTP入力と出力をSJISに変換する事で対処する。UTF-8、EUC-JP環境と異なる部分のみ記述します。
default_charset="Shift_JIS" †
ダイナミックコンテンツの文字コードセットは必ず指定しなければならない。(セキュリティ上の理由。詳細は2000年2月のCERTのXSSアドバイザリを参照)
mbstring.input_encoding="pass" †
現在のブラウザでHTMLを記述した文字エンコーディング以外で文字を送信してくるようなブラウザはない。(携帯などモバイル環境を除く)基本的にはdefault_charsetからmbstring.internal_encodingに手動で変換する。自動変換でも構わないが、使用しているPHPのバージョンが不正文字エンコーディングの検出回数を記録できない場合、必ず"pass"に設定して不正な文字エンコーディングが無いかチェックする。
mbstring.internal_encoding="UTF-8"または"EUCJP-win" †
内部エンコーディングはUTF-8またはEUCJP-winの方が良い。スクリプト、データベースの文字エンコーディングは選択した文字エンコーディングに合わせる。
mbstring.output_encoding="SJIS-win" †
出力バッファにmb_output_handlerが登録されていないとこの設定は有効にならない。mb_output_handlerは圧縮バッファよりも後、他のバッファより前に登録されなければならない。
その他 †
PHP 5.1.3, PHP 4.4.3から新しい設定が追加されました。
- mb_check_encoding関数 文字エンコーディングが壊れていないか確認する。
- mb_get_info関数にillegal_chars設定が追加された。mb_get_info('illegal_chars')でmb_convert_encodin等で検出した不正文字の数を取得できる。
いつ追加されたか失念しましたがphp.ini設定のmbstring.strict_detectionを有効に設定し、文字の自動認識に失敗した場合にエラーを発生させる事が可能になりました。
PHP(mbstring)的に最も効率が良い文字エンコーディングはUTF系の文字エンコーディングです。これはmbstring内部では全ての文字エンコーディングをUnicodeに変換してから別の文字エンコーディングに変換するからです。PHP6でもデフォルトの文字エンコーディングはUTF-8になります。PCREもマルチバイト文字はUTF-8しか利用できません。SQLiteもUTF-8のみサポートしています。XMLもデフォルトはUTF-8です。このような条件からもUTF-8最も効率が良い文字エンコーディングと言えると思います。しかし、UTF(Unicode)には正規化が行われるのが仕様なのでこの事を知らずに処理するとセキュリティホールが生まれます。RFCにも注意点が記載されているのでそれらを参照すると良いでしょう。