PHPでJSONを扱う方法
JSONは最も一般的に使用されるデータシリアライズ形式の一つです。JavaScript内での起源から成長し(JSONはJavaScript Object Notationの略)、多くのWeb APIや設定システムでの選択フォーマットとなっています。
PHPには組み込みのJSONサポートがあります。歴史的に、この機能は別の拡張として提供されていました。2020年にPHP 8.0がリリースされ、JSONは削除できない永久的なアクティブ拡張に変わりました。
JSONデータを読む
JSONデータを解析するには、次のようにします。
json_decode()関数。その完全なシグネチャは次のとおりです:
json_decode(string $json, bool|null $associative=null, int $depth=512, int $flags=0) : mixed;
最も単純な呼び出しは、他の引数を使わずにJSON文字列を渡すことです。私たちはこれに取り組みます。
{"foo": "bar"}PHPのジェネリックのインスタンスにデコードされる
stdClass私たちの新しいオブジェクトにはプロパティがあります。
fooの価値で
bar関連配列を受け取りたい場合は、渡してください
trueへ
$associativeのパラメーター
json_decode()上記の例は次のようにデコードされます。
["foo" => "bar"]その
$depthパラメータは、解析する最大ネストレベルを制御します。あなたは得られます
null
設定されたレベルよりもJSONが深くネストされている場合、データを解析しようとはしません。
その
$flagsパラメータは、解析の挙動を変更するオプションフラグのビットマスクを受け入れます。これらはPHPマニュアルで詳細に説明されており、特定のデータタイプの取り扱い方法を定義することができます。
解析エラーの処理
デフォルトでは、
json_decode()戻ります
null無効なJSON文字列が渡されたとき。これは孤立した状況を引き起こすため、問題を呈します。
null正当なJSON文字列です。あなたにはそれがどのようなものであるか知る方法がありません。
null戻り値はJSONが含まれているためです
null、またはJSONが不正で解析できなかったためです。
PHP 7.3は、この長年の問題に対処するために、次のものを追加しました。
JSON_THROW_ON_ERROR
フラグ。この定数を渡してください。
$flagsのパラメーター
json_decode()無効なJSONが検出されたときにPHPが例外をスローするようにするには:
json_decode("['malformed json", true, 512, JSON_THROW_ON_ERROR);この動作を有効にすることは一般的に望ましいですが、実行がかなり扱いにくくなります。PHP 8の名前付き引数を使うことで、オプションのパラメータに対して明示的な値を渡す必要がなくなるため、少し簡素化することができます:
json_decode(json: "['malformed json", flags: JSON_THROW_ON_ERROR);上記の2つの例は互いに同等です。唯一の違いは、後者の構文がPHP 8を必要とすることです。
データをJSONにシリアライズする
PHPの値をJSON文字列にシリアライズすることができます。
<a href="https://www.php.net/manual/en/function.json-encode.php" target="_blank" rel="noopener">json_encode()</a>関数。そのシグネチャは次の通りです:
json_encode(mixed $value, int $flags=0, int $depth=512) : string|false;PHPは任意の値を受け入れます
$valueリソースを除いて、データ型は自動的に処理され、生成されたJSON内で適切にマッピングされることが保証されます。PHPオブジェクトや連想配列は、入力値のすべての列挙可能なプロパティ/キー-値ペアを含むJSONオブジェクトになります。PHPのスカラ型は変換なしでJSONに直接マッピングされます。
その復号対照のように、
json_encode()受け入れる
$flagsそして
$depthパラメータ。ただし順序には注意してください - PHP標準ライブラリの奇妙な特性により、これらの二つのオプショナルパラメータの位置が入れ替わっています。
json_decode()データをエンコードする際には、さらに多くのフラグがサポートされています。ここで注意すべきいくつかを紹介します:
JSON_FORCE_OBJECT[]["foo" => "bar"]JSON_PRETTY_PRINTJSON_PRESERVE_ZERO_FRACTION0.00JSON_NUMERIC_CHECK"234.5"234.5JSON_PARTIAL_OUTPUT_ON_ERROR
- PHPの数値配列を配列ではなくJSONオブジェクトに変換します。これにより、変数が空の連想配列を含む場合のケースを処理できます。配列が空の場合()、JSON配列が作成され、空でない場合()、代わりにオブジェクトが生成されます。このフラグを有効にすることで、エンコードされたJSONでは常にオブジェクトが使用されることが保証されます。
- PHPのJSON出力は通常、最小化されており、HTTPリクエストの一部としてネットワークを介して送信する際には理想的です。このフラグを設定すると、JSON文字列に改行文字と自動インデントが追加され、人間が出力を読むシナリオや設定ファイルにより適した形式になります。
- PHPに、浮動小数点数を正確にエンコードさせるため、JSONに書き込む際に小数部分を切り捨てるのではなく(それが不正確に整数として解析される可能性がある)、そのままの形で書き出させます。
- JSON出力では、数値文字列を文字列として保持する代わりに自動的に数値に変換します。これを有効にすると、PHPの値はJSONとして出力されます。
- エンコーディングエラーが発生しても、執筆を続けるようにしてください。PHPは、たとえそれが完全でなくても、出力を生成するために無効な値を代わりに使おうとします。
PHPの文書内でフラグの完全なリストを取得できます。残りは主に特定のシナリオで使用するエンコーディングをカスタマイズするための特定のオプションです。
アプリケーションのドメイン層にJSONを持ち込む
複雑なウェブバックエンドは、HTTPレスポンスを出力する文脈でPHPのJSON機能を使用する可能性が高いです。つまり、おそらくドメイン層クラスのインスタンスをエンコードすることになります。
BlogPost呼ぶ
json_encode()クラスのインスタンスを使用すると、単一のオブジェクトを含むJSON文字列が生成されます。PHPはクラスの公開プロパティを列挙し、それらをキー/バリューのペアとしてJSONエンコードされたオブジェクトに追加します。
class BlogPost {
protected int $Id = 1;
public string $Title = "Example";
}
// produces '{"Title": "Example"}'
$json = json_encode(new BlogPost());
PHPは保護されたプロパティやプライベートプロパティに自動的にアクセスできません。したがって、このデフォルトの実装は、最も単純なクラスを除いて不十分です。その代わりに、あなたのクラスは次のように実装できます。
JsonSerializableインターフェース。これにより、インスタンスがJSONにどのように変換されるかを定義できます。
JsonSerializable単一のメソッドを定義します、
jsonSerialize()インスタンスがJSONにシリアライズされる必要があるときにPHPが呼び出すもの:
class BlogPost implements JsonSerializable {
protected int $Id = 1;
public string $Title = "Example";
public function jsonSerialize() {
return [
"Id" => $this -> Id,
"Title" => $this -> Title
];
}
}
// produces '{"Id": 1, "Title": "Example"}'
$json = json_encode(new BlogPost());
実装する
JsonSerializableシリアル化プロセスを制御することができます。インスタンスは、保護されたプロパティ、動的に計算された値、メソッド呼び出しからのデータを含む、何を公開するかを選択できます。
配列を返す必要すらありません。
jsonSerializableメソッドシグネチャはを指定します
mixed戻り値の型であるため、PHPがJSONにシリアライズできる任意の値を提供できます。別のオブジェクトを返して、PHPが再帰的にシリアライズすることもできます。
