記事一覧

PHPで json をレスポンスする場合には UTF8(BOMあり)に注意




目次




PHPでハマってしまったこと

ハロー、みなさん。エジソンです。

PHPerの皆様に置かれましては、益々ご健勝に、本日もPHPのコーディングの勤しんでいることかと思います。そんな、PHPerの皆様の一助となるかもしれないエントリを書き記すべく、キーボードに指を置いた次第です。

先日、起きた事件の概要を三行で記すと以下のようになります。
  • PHPでjson文字列を送出して、ブラウザで受信する。
  • ブラウザでパースエラーが発生。受信したjson文字列にUTF8のBOM文字列が含まれているのが原因。
  • 実行するPHPファイルが”BOM付きUTF8”で保存されているとエラーになる。

エラーの始まり

その事件は、ブラウザでjsonパースエラー(JavaScriptエラー)が発生したことで顕在化しました。

サーバーサイドでは、PHPでjsonエンコードされた文字列をレスポンスとして送出し、クライアントブラウザではajaxでサーバー通信してレスポンスをjsonとして受け取るという、何ら変わったことのない機能の一つです。

この現象は全ての端末で再現するというわけではなく、正常に動作する端末もあれば、別の端末ではエラーが生じるという、一貫性のないことも厄介さに拍車をかけていたのです。

原因は謎の文字列 "U+FEFF"

ブラウザの開発ツールで、レスポンスを確認してサクラエディタに貼り付けてみたところ、末尾に U+FEFF という謎の文字を発見しました。



実はこの U+FEFF というのは、BOMと呼ばれています。

Wikipedia - バイトオーダーマーク
バイトオーダーマーク (byte order mark) あるいはバイト順マーク(バイトじゅんマーク)は通称BOM(ボム)といわれる、Unicodeの符号化形式で符号化したテキストの先頭につける数バイトのデータのことである。このデータを元にUnicodeで符号化されていることおよび符号化の種類の判別に使用する。 …

PHPでは、通常一度のリクエスト中に、関連するファイル群を include します。これらの include ファイルの中に、BOM付きのUTF8のファイルが混在している状態で、json文字列をレスポンスとして送出すると、BOM(U+FEFF)制御コードも含まれるのです。


そして、ブラウザ側でjsonパースする際に、制御コードが含まれていると正しくパースできないため、JavaScriptエラーが誘発されるということなのです。

根源はジャイアニズムの体現者 Windows大先生

なんと、今回の犯人は Windows大先生、その人でした。

Windowsでは、メモ帳しかり、WindowsのファイルAPIしかり、 UTF8 = BOM付きUTF8 という公式が成立する、世界とは逆行したスタンダードを提唱している派閥なのです。
参考
DOBON.NET - BOM無しのUTF-8でテキストファイルに書き込む
逆襲のニート - BOM付きUTF-8による空白行

ある端末では正常で、他の端末で異常になってしまっている現象というのは、他の端末においてPHPの設定ファイルをメモ帳で直接編集したため、BOM付きUTF8として保存されてしまったのが、原因でした。

まとめ

PHPでUTF8と言えばBOMなしです。BOM付きUTF8に気をつけましょうというお話。

さすが、Windows大先生。そこにしびれるあこがれるう。
関連記事

このエントリーをはてなブックマークに追加

コメント

コメントの投稿

非公開コメント

プロフィール

EZOLABブログへようこそ。
EZOLABは、札幌のソフトウェア会社です。

http://ezolab.co.jp