LoginSignup
5
7

More than 5 years have passed since last update.

PHP5から7系への移行時には json_decodeの処理にご注意

Posted at

PHP5.6から7.2に移行したときにけっこうな地雷を踏んだのでここに記録しておく。

対象

  • remiでphp56とphp-jsonをインストールしてる人
  • PHPアプリケーションに投げられてくるJSON文字列が、自分のコントロール範囲外の人

ハマったポイント

  • remiで入るPHPのJSON Parserは、php-pecl-jsonc(JSON-C)が使われている
  • JSON-Cは、本来エスケープされているべき文字列が、エスケープされていなくても ちゃんと処理できちゃう
  • ↑こいつらを、PHP7で入るJSON Parserでは、ちゃんとエラーにする(とても正しい)
  • クソJSONを送ってきてるクライアントがいたが、PHP5.6時代にはちゃんと処理しちゃっていたので、問題に気づかず
  • PHP7.2に移行したら、クライアントが送ってきたリクエストをエラー扱いして処理できなくなる

検証

docker環境を作って確認

確認用プログラム

  • エスケープしてないタブを含んだJSONを処理してみる
test.php
<?php

echo "PHP v". phpversion(). "\n";

if (defined('JSON_C_BUNDLED')) {
    echo "JSON-C\n";
}  else {
    echo "Not JSON-C\n";
}

$invalidJson = '{"item":"Invalid' . "\t" . 'JSON"}';

$decodeJson = json_decode($invalidJson);
echo 'json_last_error_msg: '.json_last_error_msg()."\n";
var_dump(json_encode($decodeJson));

remi-php56 + php-json(php-pecl-jsonc)

cent7-php56/Dockerfile
FROM centos:centos7

RUN yum clean all && yum -y update
RUN yum install -y http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
RUN yum clean all

### php
RUN yum -y --enablerepo=remi-php56 install \
php \
php-json
実行結果
% docker build cent7-php56 -t cent7-php56
% docker run --rm -v $(pwd):/app -w /app cent7-php56 php test.php
PHP v5.6.38
JSON-C
json_last_error_msg: No error
string(24) "{"item":"Invalid\tJSON"}"
  • 正しくないJSONをjson_decodeに喰わせてもエラーにならない

remi-php70 + php-json

cent7-php70/Dockerfile
FROM centos:centos7

RUN yum clean all && yum -y update
RUN yum install -y http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
RUN yum clean all

### php
RUN yum -y --enablerepo=remi-php70 install \
php \
php-json
実行結果
% docker build cent7-php70 -t cent7-php70
% docker run --rm -v $(pwd):/app -w /app cent7-php70 php test.php
PHP v7.0.32
Not JSON-C
json_last_error_msg: Control character error, possibly incorrectly encoded
string(4) "null"
  • 正しくないJSONをjson_decodeに喰わせるとエラーになり、nullを返す

結論

  • クソJSONを投げてくるクライアントが悪いんだから、クライアント側を直させましょう
  • PHP7系で引き続きクソJSONをパースする方法は知らない

参考

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7