PHP – マジッククォートとSJISの文字化け問題

【この記事の所要時間 : 約 5 分

PHPには、マジッククォート(magic quotes)というものがある。これは、php.ini にて、magic_quotes_gpc が ON になっている場合に有効となる機能であり、GPC(Get/Post/Cookie)からの入力値について以下のパターンで変換する。
「”」 → 「\”」
「’」 → 「\’」
「\」 → 「\\」
これは、\ (バックスラッシュ)によるエスケープとも呼ばれる。
このマジッククォートは、文字コードがSJISの時に意外な問題(文字化け)が発生する。
それは、以下のようなものである。
「表」 → 「表\」
「能」 → 「能\」
「申」 → 「申\」
「貼」 → 「貼\」
なぜ「”」でも「’」でも「\」でもない文字なのに変換(エスケープ)されているのか?理由は、文字コードにある。まず 「\」はSJISの文字コードで表すと、「5C」となり、上記の例で出てきた、表や能、申、貼などのSJISの文字コードは、以下のように後ろに「5C」がついている。
表(955C)
能(945C)
申(905C)
貼(935C)
つまり、文字コード上、たまたま「5C」がついているために、「5C」が「\」であると認識されてエスケープされるという悲劇が生じていたのである。実際のところ、マジッククォートが有効になっている場合、SJISの文字コードベースでは以下のような変換になっている。
「”(22)」 → 「\”(5C22)」
「’(27)」 → 「\’(5C27)」
「\(5C)」 → 「\\(5C5C)」
よって、
「表(955C)」 → 「表\(955C5C)」
「能(945C)」 → 「能\(945C5C)」
「申(905C)」 → 「申\(905C5C)」
「貼(935C)」 → 「貼\(935C5C)」
という変換になっていたのである。
つまり、SJISの文字コード上、5Cが含まれる文字は、こういった文字化けの対象となり、上記の4つ以外にもかなりの数ある。Wikipediaにも載っている。
Wikipedia – Shift_JIS

2バイト目が5C等に成りうることによる問題
Shift_JISでは、「ソ」「噂」など一部の字の2バイト目に、5C16(Shift_JISでは¥記号、ASCIIなどではバックスラッシュ)を使用している。多くのプログラミング言語 (C、Perl、Bourne Shellなど多数) では、この5C16をエスケープ文字としている。したがって、ソースコードや文字データの処理においてShift_JISを想定していないプログラミング環境では問題が起こる。この問題は、同じように2バイト目の範囲に5C16を含むBig5や、まれではあるがGBKなどの文字コードでも発生しうる。
現在でも、シングルバイト文字コード対応のソフトウェアをShift_JIS環境で使用すると、改行などの動作やファイル名の処理などにしばしばこの問題がつきまとう。この不具合を招く、2バイト目に5C16を持つ文字のことを、だめ文字と呼び、この中には「ソ」「構」「能」「表」など一般に使用頻度の高い文字もある。

では対策はどうしたらいいのかであるが、非常にカンタンで、このマジッククォート機能を使わなければいいのである。

if ( get_magic_quotes_gpc( ) ) {
$string = stripslashes($string);
}

というような感じで、magic_quotes_gpc が ON の場合は、stripskashes( ) 関数で文字列に付加されているバックスラッシュのエスケープを解除し、magic_quotes_gpc が OFF の場合は、何もしないという分岐処理をいれてやればよい。
PHP : マジッククオート – Manual

警告
この機能は 非推奨 であり、PHP 6.0.0 で 削除 されます。この機能を使用しないことを強く推奨します。

とあり、基本的にはマジッククォート機能は OFF であることが強く推奨されている。
UTF-8 や EUC といった文字コードで開発している人も多いかと思うが、まだまだSJISを使わなければならないケースはある(携帯サイトとか)。そういう場合にはマジッククォートにも注意してもらいたい。
文字から文字コードを表示する
PHPのShift_JIS文字化け対策1
特定の文字(表・予・申・能など)が文字化けする
より詳しく知りたい方はこちらへ

プログラミングPHP 第3版
プログラミングPHP 第3版

posted with amazlet at 15.11.19
Kevin Tatroe Peter MacIntyre Rasmus Lerdorf
オライリージャパン
売り上げランキング: 44,636
スポンサーリンク
レクタングル(大)広告
  • このエントリーをはてなブックマークに追加
スポンサーリンク
レクタングル(大)広告

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です