2011.06.16

【FAQ】『PHPによるWebアプリケーションスーパーサンプル 第2版』

PHPによるWebアプリケーションスーパーサンプル 第2版

●質問:15-3アンケートのソースコードについて関し
 cnv_sqlstr関数などで使われている文字コードを変換する手法について不明なところがあります。

 

859:function cnv_sqlstr($string) {
860:    // 文字コードを変換する
861:    $det_enc = mb_detect_encoding($string, ENCDISP .
", " . ENCDB);
862:    if ($det_enc  and $det_enc != ENCDB) {
863:        $string = mb_convert_encoding($string, ENCDB, $det_enc);
864:    }
865:    // バックスラッシュを付加する
866:    $string = addslashes($string);
867:    return $string;
868:}

 

 ENCDISP とENCDBが同じ文字コード(EUC-JP)で定義されています。
 ということは、

861:mb_detect_encodingを使って、"EUC-JP,EUC-JP"というリストの中から文字コード検出をしている。

862:検出された文字コードがリストに存在していて(="EUC-JP")、かつ、EUC-JPではない場合、
863:文字列をEUC-JPに変換する。

というように解析できます。

 862行目のif条件がよくわかりません。
 861でmb_detect_encodingの引数が"EUC-JP,EUC-JP"というリストになっているので、"検出された文字コードがリストに存在しない場合、"という1つの条件だけで済むような気がするのですが。

●回答
 ご指摘のコード

$det_enc = mb_detect_encoding(… → (1)文字コードの検出
if ($det_enc  and $det_enc != ENCDB → (2)文字コード変換の条件

 (1)で検出した文字コード$det_encがデータベースの文字コードENCDBと異なる場合は(2)以下の文字コード変換を実行するという流れです。

 たとえば、$det_encがEUC-JP、ENCDBがUTF-8というような場合に文字コード変換が実行されます。

 if文の「$det_enc  and」の判断が無駄ではないのかというご指摘かと思います。記憶が定かではありませんが、これは執筆時点のバージョンのPHPで文字コード検出が失敗する現象があったので、とりあえずの回避策として組み込んだのではないかと記憶しています。

 これが唯一絶対の正解コードではありませんので、お使いのPHPバージョンで不要と思われる条件判断を省略したり、より効率的な処理コードにまとめるなどして、よりよいコードにカスタマイズしてお使いいただければ幸いです。