緒言
ホームページを作っていたらPHPでJSONファイルを読み込む際,何故かデコードで失敗する現象に遭遇しました.その原因と解決策について今回は説明します.
問題
まずは修正前のコードを示します.読み込むJSONファイルも含めて問題なさそうに見えます.しかし,このまま実行するとjson_decode
でnull
が返されるため,正常に読み込めません.
$json = file_get_contents("data.json");
$json = json_decode($json, true);
var_dump($json); // null
echo json_last_error_msg(); // syntax error
原因
この現象はテキストの先頭に付与されるバイト順マークが原因でした.これは頭文字を取ってBOMとも呼ばれており,本来はエンディアンを指定する特殊な符号です.ここでJSONファイルを改めて確認したところ,エンコーディングがUTF-8となっており,確かにBOMが付与されていました.なお,エディタでBOMが付与されないエンコーディングであるUTF-8Nに変更したところ,正常に読み込めました.
解決策
まず,エンコーディングがUTF-8以外であっても安全に読み込むため,mb_convert_encoding
でエンコーディングをUTF-8に指定します.そして問題のBOMが付与されている場合はPHPで取り除きます.以下に修正版のコードを示します.
$json = file_get_contents("data.json");
$json = mb_convert_encoding($json, 'UTF-8', 'auto');
if (substr($json, 0, 3) === "\xEF\xBB\xBF") {
$json = substr($json, 3);
}
$data = json_decode($json, true);
結言
これで無事にJSONファイルを読み込めるようになりました.適切なエラー処理も併せて記述することが本来は望ましいですが,今回は静的解析されていることを前提に割愛しました.ご容赦ください.