Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】json_validate()関数の使い方

json_validate関数の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

json_validate関数は、与えられた文字列が有効なJSON形式であるかどうかを検証する関数です。この関数は、JSON文字列を解析し、エラーが発生しなければtrueを、エラーが発生すればfalseを返します。JSON (JavaScript Object Notation) は、データを構造化して表現するための軽量な形式であり、主にウェブアプリケーションやAPIにおいてデータの交換に用いられます。json_validate関数を使用することで、受信したデータや生成されたデータが正しいJSON形式であるかを事前に確認し、エラーを未然に防ぐことができます。

この関数は、PHP 8.3で導入され、それ以前のバージョンでは利用できません。JSONデータの検証は、データの整合性を保つ上で非常に重要です。例えば、APIから受信したデータが期待される形式と異なると、アプリケーションの動作に予期せぬ影響を及ぼす可能性があります。json_validate関数を使用することで、このような問題を早期に検出し、適切なエラー処理を行うことができます。

具体的には、json_validate関数は、入力された文字列をJSONとして解釈できるかどうかを判断します。解釈可能であればtrueを返し、構文エラーやその他の理由で解釈できない場合はfalseを返します。この関数は、JSONデータのデコード処理を行う前に、データの有効性を確認するために使用されることが一般的です。デコード処理 (json_decode関数など) は、無効なJSONデータに対して実行するとエラーが発生する可能性があるため、事前にjson_validate関数で検証することで、より安定したアプリケーションを開発できます。

構文(syntax)

1json_validate(string $json, int $depth = 512, int $flags = 0): bool

引数(parameters)

string $json, int $depth = 512, int $flags = 0

  • string $json: 検証するJSON文字列
  • int $depth = 512: 再帰の深さの上限
  • int $flags = 0: オプションフラグ

戻り値(return)

bool

JSON文字列が有効なJSON形式である場合にtrueを、そうでない場合にfalseを返します。

サンプルコード

PHP 8 json_validateでJSONを検証する

1<?php
2
3/**
4 * json_validate関数の基本的な使い方と、JSONバリデーションの重要性を示すサンプルコードです。
5 * システムエンジニアを目指す初心者の方にも分かりやすいように、PHP 8以降で利用可能な
6 * この関数がどのようにJSON文字列の形式をチェックするかを示します。
7 */
8function demonstrateJsonValidation(): void
9{
10    echo "--- JSON文字列の形式バリデーション ---" . PHP_EOL . PHP_EOL;
11
12    // 1. 有効なJSON文字列の例
13    $validJson = '{"name": "Alice", "age": 30, "city": "New York"}';
14
15    // 2. 無効なJSON文字列の例 (キーが引用符で囲まれていない)
16    $invalidJsonMalformedKey = '{name: "Bob", "age": 25}';
17
18    // 3. 無効なJSON文字列の例 (末尾に不要なカンマがある)
19    $invalidJsonTrailingComma = '{"item": "apple", "price": 1.5,}';
20
21    // 有効なJSONのバリデーション
22    echo "検証対象 (有効なJSON): " . $validJson . PHP_EOL;
23    if (json_validate($validJson)) {
24        echo "結果: 有効なJSON形式です。" . PHP_EOL;
25    } else {
26        echo "結果: 無効なJSON形式です。" . PHP_EOL;
27    }
28    echo PHP_EOL;
29
30    // 無効なJSON (キーの形式エラー) のバリデーション
31    echo "検証対象 (無効なJSON - キーの形式エラー): " . $invalidJsonMalformedKey . PHP_EOL;
32    if (json_validate($invalidJsonMalformedKey)) {
33        echo "結果: 有効なJSON形式です。" . PHP_EOL;
34    } else {
35        echo "結果: 無効なJSON形式です。" . PHP_EOL;
36    }
37    echo PHP_EOL;
38
39    // 無効なJSON (末尾のカンマエラー) のバリデーション
40    echo "検証対象 (無効なJSON - 末尾カンマエラー): " . $invalidJsonTrailingComma . PHP_EOL;
41    if (json_validate($invalidJsonTrailingComma)) {
42        echo "結果: 有効なJSON形式です。" . PHP_EOL;
43    } else {
44        echo "結果: 無効なJSON形式です。" . PHP_EOL;
45    }
46    echo PHP_EOL;
47
48    echo "--- オプション引数 'depth' の使用例 ---" . PHP_EOL . PHP_EOL;
49
50    // 深いネストを持つJSON文字列
51    $deeplyNestedJson = '{"a":{"b":{"c":{"d":{"e":{"f":{"g":1}}}}}}}'; // このJSONの深さは 7
52
53    // depthを5に設定してバリデーションを試みる
54    echo "検証対象 (深いネストのJSON): " . $deeplyNestedJson . PHP_EOL;
55    echo "許可された最大深度を '5' とした場合:" . PHP_EOL;
56    if (json_validate($deeplyNestedJson, 5)) {
57        echo "結果: 有効なJSON形式です (深度5以内)。" . PHP_EOL;
58    } else {
59        echo "結果: 無効なJSON形式です (指定された最大深度 '5' を超えています)。" . PHP_EOL;
60    }
61    echo PHP_EOL;
62
63    // depthを10に設定してバリデーションを試みる
64    echo "許可された最大深度を '10' とした場合:" . PHP_EOL;
65    if (json_validate($deeplyNestedJson, 10)) {
66        echo "結果: 有効なJSON形式です (深度10以内)。" . PHP_EOL;
67    } else {
68        echo "結果: 無効なJSON形式です (指定された最大深度 '10' を超えています)。" . PHP_EOL;
69    }
70    echo PHP_EOL;
71}
72
73// 上記のデモンストレーション関数を実行します。
74demonstrateJsonValidation();
75
76?>

json_validate関数は、PHP 8以降で利用可能な、JSON文字列の形式が正しいかどうかを検証するための関数です。ウェブアプリケーションなどで外部から受け取ったJSONデータが、期待される形式に従っているかを確認する際に役立ちます。

この関数は、検証したいJSON文字列を最初の引数$jsonとして受け取ります。もしJSONの形式が正しければtrueを、無効な形式であればfalseを戻り値として返します。これにより、開発者はjson_decodeを実行する前にJSONの妥当性をチェックし、パースエラーを防ぐことができます。

サンプルコードでは、まず有効なJSON文字列のほか、キーが引用符で囲まれていないJSONや末尾に不要なカンマがあるJSONといった、一般的な無効な形式の例を用いて、json_validateがどのようにそれらのエラーを検出するかを示しています。これらの無効なJSONに対しては、関数はfalseを返します。

また、オプションの第二引数$depthを使用すると、JSONが許容する最大深度を指定できます。例えば、極端に深くネストされたJSON文字列に対して、$depthで指定した深さを超える場合は、そのJSONは無効と判断されfalseが返されます。これにより、意図しないデータの深さからくる問題を未然に防ぎ、システムの堅牢性を高めることが可能です。

この関数を利用することで、不正なJSONデータが原因で発生するエラーを減らし、より信頼性の高いシステムを構築できます。

json_validate関数は、PHP 8以降でJSON文字列の構文が正しいかを手軽に検証できます。この関数は、JSONの形式が仕様に沿っているかだけを確認し、データの内容や型まではチェックしません。そのため、例えば年齢が数値であるかといった、より詳細なデータの妥当性検証は別途行う必要があります。

また、json_decodeと異なり、データをデコードせず、純粋に構文チェックに特化している点が特徴です。引数の$depthは、JSONのネストの深さを制限し、深いJSONによるメモリ消費や処理の遅延を防ぐセキュリティ対策としても利用できます。無効なJSONを事前に排除することで、プログラムの安定性を向上させることができます。

PHP 8.4 json_validate を使ったJSONスキーマ検証

1<?php
2
3/**
4 * JSON文字列の構文と、簡易的なスキーマ(必須キーの存在)を検証します。
5 *
6 * この関数は、まず `json_validate()` を用いてJSON文字列の構文が
7 * 正しい(well-formed)かを高速にチェックします。
8 * その後、指定された必須キーがJSONオブジェクトにすべて存在するかを
9 * 検証することで、簡易的なスキーマチェックを行います。
10 *
11 * より複雑な型チェックやパターン検証など、本格的なJSON Schema仕様に
12 * 基づく検証が必要な場合は、専用のライブラリの使用を検討してください。
13 *
14 * @param string $json   検証対象のJSON文字列。
15 * @param array  $schema 検証する必須キーのリスト。例: ['id', 'name']
16 * @return bool JSONが構文的に正しく、かつスキーマを満たす場合は true、それ以外は false。
17 */
18function validateJsonAndSchema(string $json, array $schema): bool
19{
20    // 手順1: `json_validate()` でJSONの構文が正しいかをチェックします。
21    // これにより、不正な形式のJSONを効率的に弾くことができます。
22    if (!json_validate($json)) {
23        return false;
24    }
25
26    // 手順2: 構文が正しいことを確認後、JSONをPHPの連想配列にデコードします。
27    // エラー時に例外をスローするフラグを指定しています。
28    try {
29        $data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
30    } catch (JsonException $e) {
31        // json_validate()を通過していれば通常ここには到達しません。
32        return false;
33    }
34    
35    // 手順3: 簡易的なスキーマ検証として、必須キーがすべて存在するかをチェックします。
36    foreach ($schema as $requiredKey) {
37        if (!array_key_exists($requiredKey, $data)) {
38            // 必須キーが一つでも欠けていれば検証失敗とします。
39            return false;
40        }
41    }
42
43    // すべての検証を通過した場合のみ true を返します。
44    return true;
45}
46
47// --- 以下、サンプルコードの実行例 ---
48
49// 検証に用いるスキーマ(ユーザー情報として 'id' と 'name' を必須とする)
50$userSchema = ['id', 'name', 'email'];
51
52// ケース1: 構文も正しく、スキーマも満たすJSON
53$validJson = '{"id": 1, "name": "Taro Yamada", "email": "taro@example.com", "age": 30}';
54echo "ケース1(正常): " . (validateJsonAndSchema($validJson, $userSchema) ? 'OK' : 'NG') . PHP_EOL;
55
56// ケース2: 構文は正しいが、スキーマを満たさないJSON('email' キーが欠落)
57$missingKeyJson = '{"id": 2, "name": "Jiro Suzuki"}';
58echo "ケース2(スキーマ不適合): " . (validateJsonAndSchema($missingKeyJson, $userSchema) ? 'OK' : 'NG') . PHP_EOL;
59
60// ケース3: 構文が不正なJSON(末尾に余分なカンマ)
61$invalidSyntaxJson = '{"id": 3, "name": "Saburo Tanaka", "email": "saburo@example.com",}';
62echo "ケース3(構文エラー): " . (validateJsonAndSchema($invalidSyntaxJson, $userSchema) ? 'OK' : 'NG') . PHP_EOL;
63
64?>

このサンプルコードは、PHPのjson_validate関数を使用して、JSON文字列の妥当性を検証する方法を示しています。json_validateは、第一引数で受け取った文字列がJSONとして正しい構文であるかをチェックし、結果をbool値(真偽値)で返します。正しい場合はtrue、不正な場合はfalseとなります。この関数は、実際にJSONをデコードしてPHPのデータに変換するjson_decodeよりも高速に動作するため、構文チェックのみを目的とする場合に効率的です。

コード内のvalidateJsonAndSchema関数は、二段階の検証を行います。まず、引数$jsonで受け取った文字列をjson_validateで検証し、構文が不正であれば即座にfalseを返します。構文が正しい場合、次にjson_decodeでPHPの連想配列に変換します。その後、第二引数$schemaで指定された必須キーのリストを元に、変換後のデータに必要なキーがすべて存在するかをarray_key_existsで一つずつ確認します。構文が正しく、かつ必須キーがすべて揃っている場合にのみ、この関数は最終的にtrueを返します。これにより、JSONデータの形式と構造の両方を簡易的に検証できます。

json_validate()関数はJSONの構文、つまり文法が正しいかだけを高速にチェックします。この関数だけでは、データの中身(例えば、必須キーの有無や値の型)までは検証できません。サンプルコードの後半で行っているキーの存在チェックは、あくまで簡易的なスキーマ検証です。そのため、キーはあっても値が空だったり、期待と違う型(数値のはずが文字列など)だったりした場合は検出できない点に注意が必要です。また、json_decode()関数の第二引数にtrueを指定して連想配列に変換しないと、その後のキー存在チェックが正しく動作しません。なお、このjson_validate()関数はPHP 8.3以降で利用可能です。

PHPでJSONをスキーマ検証する

1<?php
2
3/**
4 * JSON文字列が、指定されたスキーマ(構造定義)に適合するかを検証します。
5 *
6 * この関数は2段階の検証を行います。
7 * 1. json_validate() を使用して、文字列が構文的に有効なJSONであるかを確認します。
8 * 2. JSONをデコードし、必須キーの存在と各キーの値のデータ型がスキーマ定義と一致するかを確認します。
9 *
10 * @param string $jsonString 検証対象のJSON文字列
11 * @param array $schema 検証ルールを定義したスキーマ配列。例: ['name' => 'string', 'age' => 'integer']
12 * @return bool JSONがスキーマに適合する場合にtrue、そうでない場合にfalseを返します。
13 */
14function validateJsonAgainstSchema(string $jsonString, array $schema): bool
15{
16    // ステップ1: JSONの構文が正しいか検証する (PHP 8.3以降で利用可能)
17    if (!json_validate($jsonString)) {
18        // 構文的に無効なJSON
19        return false;
20    }
21
22    // JSON文字列をPHPの連想配列に変換
23    $data = json_decode($jsonString, true);
24
25    // ステップ2: スキーマに基づいて構造と型を検証する
26    foreach ($schema as $key => $expectedType) {
27        // キーが存在するかチェック
28        if (!array_key_exists($key, $data)) {
29            return false; // 必須キーが不足している
30        }
31
32        // キーに対応する値を取得
33        $value = $data[$key];
34
35        // 期待されるデータ型と実際のデータ型が一致するかチェック
36        $actualType = gettype($value);
37        $isValidType = match ($expectedType) {
38            'string' => $actualType === 'string',
39            'integer' => $actualType === 'integer',
40            'double' => $actualType === 'double', // float型も含む
41            'boolean' => $actualType === 'boolean',
42            'array' => $actualType === 'array',
43            'object' => $actualType === 'object',
44            'null' => $actualType === 'NULL',
45            default => false,
46        };
47
48        if (!$isValidType) {
49            return false; // データ型が一致しない
50        }
51    }
52
53    return true; // 全ての検証をパス
54}
55
56// 検証ルールとなるスキーマを定義
57// 'id'は整数、'name'は文字列、'isActive'は真偽値であることを期待
58$userSchema = [
59    'id' => 'integer',
60    'name' => 'string',
61    'isActive' => 'boolean',
62];
63
64// --- 検証の実行例 ---
65
66// 1. 成功例: スキーマに完全に適合するJSON
67$validJson = '{"id": 1, "name": "Alice", "isActive": true}';
68echo "Valid JSON: ";
69var_dump(validateJsonAgainstSchema($validJson, $userSchema)); // bool(true)
70
71// 2. 失敗例: キーが不足しているJSON ('isActive'がない)
72$missingKeyJson = '{"id": 2, "name": "Bob"}';
73echo "Missing Key JSON: ";
74var_dump(validateJsonAgainstSchema($missingKeyJson, $userSchema)); // bool(false)
75
76// 3. 失敗例: データ型が違うJSON ('id'が文字列になっている)
77$wrongTypeJson = '{"id": "3", "name": "Charlie", "isActive": false}';
78echo "Wrong Type JSON: ";
79var_dump(validateJsonAgainstSchema($wrongTypeJson, $userSchema)); // bool(false)
80
81// 4. 失敗例: 構文的に無効なJSON (末尾にカンマがある)
82$invalidSyntaxJson = '{"id": 4, "name": "Dave", "isActive": true,}';
83echo "Invalid Syntax JSON: ";
84var_dump(validateJsonAgainstSchema($invalidSyntaxJson, $userSchema)); // bool(false)

このPHPコードは、あるJSON形式の文字列が、指定されたルール(スキーマ)通りに作られているかを厳密に検証するためのカスタム関数 validateJsonAgainstSchema を定義しています。この検証は2つのステップで行われます。

まず、第一のステップとして、PHP 8.3から利用可能になった json_validate() 関数を使い、渡された文字列がJSONとして正しい構文で書かれているかを高速にチェックします。この関数は、JSON文字列を引数に取り、構文が正しければtrue、不正であればfalseを返します。構文エラーが見つかった時点で、関数は即座にfalseを返して処理を終了します。

構文チェックを通過すると、第二のステップに進みます。ここでは json_decode() を使ってJSON文字列をPHPの連想配列に変換し、より詳細な内容の検証を行います。あらかじめ定義されたスキーマ配列に基づき、必須のキーが存在するか、そして各キーの値がスキーマで指定されたデータ型(例えば「整数」や「文字列」など)と一致するかを一つずつ確認します。全てのキーとデータ型がスキーマの定義と完全に一致した場合にのみ、この関数は最終的にtrue(検証成功)を返します。一つでもルール違反があればfalse(検証失敗)を返します。

このサンプルコードは、JSONの正しさを2段階で検証します。まずjson_validate()で構文をチェックしますが、この便利な関数はPHP 8.3以降でなければ利用できない点に注意してください。次にjson_decode()でデータをPHPの配列に変換しますが、第二引数にtrueを指定して連想配列にすることが非常に重要です。この指定がないとオブジェクトが返され、後続のキー存在チェックが正しく機能しません。また、この検証関数はネストしたオブジェクトや、あってもなくてもよいオプションのキーには対応していません。スキーマに定義されていない余分なキーが含まれていても検証を通過するため、より厳密な仕様が求められる場合は、コードの追加修正や専用ライブラリの利用を検討する必要があります。

PHP 8.3でJSON形式を検証する

1<?php
2
3/**
4 * 指定されたJSON文字列の形式が有効であるか検証します。
5 *
6 * この関数はPHP 8.3以降で利用可能な json_validate 関数を使用します。
7 * システムエンジニアを目指す初心者の方がJSONデータ処理の基本を理解するのに役立ちます。
8 *
9 * @param string $jsonString 検証するJSON文字列。
10 * @return bool JSON形式が有効な場合は true、無効な場合は false。
11 */
12function isValidJson(string $jsonString): bool
13{
14    // json_validate 関数は、JSON文字列の構文が正しいかを効率的にチェックします。
15    // 第2引数 $depth はJSONの最大ネスト深度(デフォルト512)、第3引数 $flags はオプション(デフォルト0)です。
16    // これらは通常デフォルト値で問題ありません。
17    return json_validate($jsonString);
18}
19
20// --- 使用例 ---
21
22// 1. 有効なJSON文字列
23$validJson = '{"name": "Alice", "age": 30, "city": "New York"}';
24
25// 2. 無効なJSON文字列(最後の閉じ括弧が欠けている)
26$invalidJsonMissingBracket = '{"product": "Laptop", "price": 1200, "currency": "USD"';
27
28// 3. 無効なJSON文字列(キーがダブルクォーテーションで囲まれていない)
29$invalidJsonMalformedKey = '{item: "Book", "author": "John Doe"}';
30
31echo "JSON形式の検証を開始します。\n\n";
32
33// 例1: 有効なJSONの検証
34if (isValidJson($validJson)) {
35    echo "1. '$validJson' は有効なJSON形式です。\n";
36} else {
37    echo "1. '$validJson' は無効なJSON形式です。\n";
38}
39
40// 例2: 無効なJSON(閉じ括弧欠如)の検証
41if (isValidJson($invalidJsonMissingBracket)) {
42    echo "2. '$invalidJsonMissingBracket' は有効なJSON形式です。\n";
43} else {
44    echo "2. '$invalidJsonMissingBracket' は無効なJSON形式です。\n";
45}
46
47// 例3: 無効なJSON(キーの形式不正)の検証
48if (isValidJson($invalidJsonMalformedKey)) {
49    echo "3. '$invalidJsonMalformedKey' は有効なJSON形式です。\n";
50} else {
51    echo "3. '$invalidJsonMalformedKey' は無効なJSON形式です。\n";
52}
53
54?>

PHP 8.3以降で利用可能なjson_validate関数は、指定されたJSON文字列の形式が文法的に正しいかを効率的に検証し、JSONデータの整合性を確認するために使用されます。

この関数の第一引数には検証対象のJSON文字列を渡します。第二引数 $depth と第三引数 $flags はオプションですが、通常はデフォルト値のままで問題なく利用できます。

戻り値は真偽値(bool)で、JSON形式が有効な場合はtrueを、閉じ括弧の欠如やキーの形式不正など構文エラーがある場合はfalseを返します。

サンプルコードでは、json_validate関数が有効なJSON文字列にはtrue、無効なJSON文字列にはfalseを返す挙動を示しています。これにより、不正なJSONデータによるプログラムの誤動作を防ぎ、システムの堅牢性を高めることが可能です。

このサンプルコードで使用されているjson_validate関数は、PHP 8.3以降のバージョンで利用可能ですので、実行環境のPHPバージョンを必ず確認してください。この関数は、JSON文字列の構文が正しいかのみを効率的に検証します。JSON内のデータ型や値の範囲、必須項目といった「内容」の妥当性までは確認しませんのでご注意ください。検証が失敗した場合に、具体的にどのようなエラーが発生したかを知りたい場合は、json_validate関数の実行後にjson_last_error()json_last_error_msg()関数を併用すると良いでしょう。これにより、より詳細なデバッグが可能となります。

関連コンテンツ