【PHP8.x】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)
json_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.4 json_validate
を使ったJSONスキーマ検証
<?php
/**
* JSON文字列の構文と、簡易的なスキーマ(必須キーの存在)を検証します。
*
* この関数は、まず `json_validate()` を用いてJSON文字列の構文が
* 正しい(well-formed)かを高速にチェックします。
* その後、指定された必須キーがJSONオブジェクトにすべて存在するかを
* 検証することで、簡易的なスキーマチェックを行います。
*
* より複雑な型チェックやパターン検証など、本格的なJSON Schema仕様に
* 基づく検証が必要な場合は、専用のライブラリの使用を検討してください。
*
* @param string $json 検証対象のJSON文字列。
* @param array $schema 検証する必須キーのリスト。例: ['id', 'name']
* @return bool JSONが構文的に正しく、かつスキーマを満たす場合は true、それ以外は false。
*/
function validateJsonAndSchema(string $json, array $schema): bool
{
// 手順1: `json_validate()` でJSONの構文が正しいかをチェックします。
// これにより、不正な形式のJSONを効率的に弾くことができます。
if (!json_validate($json)) {
return false;
}
// 手順2: 構文が正しいことを確認後、JSONをPHPの連想配列にデコードします。
// エラー時に例外をスローするフラグを指定しています。
try {
$data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
// json_validate()を通過していれば通常ここには到達しません。
return false;
}
// 手順3: 簡易的なスキーマ検証として、必須キーがすべて存在するかをチェックします。
foreach ($schema as $requiredKey) {
if (!array_key_exists($requiredKey, $data)) {
// 必須キーが一つでも欠けていれば検証失敗とします。
return false;
}
}
// すべての検証を通過した場合のみ true を返します。
return true;
}
// --- 以下、サンプルコードの実行例 ---
// 検証に用いるスキーマ(ユーザー情報として 'id' と 'name' を必須とする)
$userSchema = ['id', 'name', 'email'];
// ケース1: 構文も正しく、スキーマも満たすJSON
$validJson = '{"id": 1, "name": "Taro Yamada", "email": "taro@example.com", "age": 30}';
echo "ケース1(正常): " . (validateJsonAndSchema($validJson, $userSchema) ? 'OK' : 'NG') . PHP_EOL;
// ケース2: 構文は正しいが、スキーマを満たさないJSON('email' キーが欠落)
$missingKeyJson = '{"id": 2, "name": "Jiro Suzuki"}';
echo "ケース2(スキーマ不適合): " . (validateJsonAndSchema($missingKeyJson, $userSchema) ? 'OK' : 'NG') . PHP_EOL;
// ケース3: 構文が不正なJSON(末尾に余分なカンマ)
$invalidSyntaxJson = '{"id": 3, "name": "Saburo Tanaka", "email": "saburo@example.com",}';
echo "ケース3(構文エラー): " . (validateJsonAndSchema($invalidSyntaxJson, $userSchema) ? 'OK' : 'NG') . PHP_EOL;
?>
このサンプルコードは、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をスキーマ検証する
<?php
/**
* JSON文字列が、指定されたスキーマ(構造定義)に適合するかを検証します。
*
* この関数は2段階の検証を行います。
* 1. json_validate() を使用して、文字列が構文的に有効なJSONであるかを確認します。
* 2. JSONをデコードし、必須キーの存在と各キーの値のデータ型がスキーマ定義と一致するかを確認します。
*
* @param string $jsonString 検証対象のJSON文字列
* @param array $schema 検証ルールを定義したスキーマ配列。例: ['name' => 'string', 'age' => 'integer']
* @return bool JSONがスキーマに適合する場合にtrue、そうでない場合にfalseを返します。
*/
function validateJsonAgainstSchema(string $jsonString, array $schema): bool
{
// ステップ1: JSONの構文が正しいか検証する (PHP 8.3以降で利用可能)
if (!json_validate($jsonString)) {
// 構文的に無効なJSON
return false;
}
// JSON文字列をPHPの連想配列に変換
$data = json_decode($jsonString, true);
// ステップ2: スキーマに基づいて構造と型を検証する
foreach ($schema as $key => $expectedType) {
// キーが存在するかチェック
if (!array_key_exists($key, $data)) {
return false; // 必須キーが不足している
}
// キーに対応する値を取得
$value = $data[$key];
// 期待されるデータ型と実際のデータ型が一致するかチェック
$actualType = gettype($value);
$isValidType = match ($expectedType) {
'string' => $actualType === 'string',
'integer' => $actualType === 'integer',
'double' => $actualType === 'double', // float型も含む
'boolean' => $actualType === 'boolean',
'array' => $actualType === 'array',
'object' => $actualType === 'object',
'null' => $actualType === 'NULL',
default => false,
};
if (!$isValidType) {
return false; // データ型が一致しない
}
}
return true; // 全ての検証をパス
}
// 検証ルールとなるスキーマを定義
// 'id'は整数、'name'は文字列、'isActive'は真偽値であることを期待
$userSchema = [
'id' => 'integer',
'name' => 'string',
'isActive' => 'boolean',
];
// --- 検証の実行例 ---
// 1. 成功例: スキーマに完全に適合するJSON
$validJson = '{"id": 1, "name": "Alice", "isActive": true}';
echo "Valid JSON: ";
var_dump(validateJsonAgainstSchema($validJson, $userSchema)); // bool(true)
// 2. 失敗例: キーが不足しているJSON ('isActive'がない)
$missingKeyJson = '{"id": 2, "name": "Bob"}';
echo "Missing Key JSON: ";
var_dump(validateJsonAgainstSchema($missingKeyJson, $userSchema)); // bool(false)
// 3. 失敗例: データ型が違うJSON ('id'が文字列になっている)
$wrongTypeJson = '{"id": "3", "name": "Charlie", "isActive": false}';
echo "Wrong Type JSON: ";
var_dump(validateJsonAgainstSchema($wrongTypeJson, $userSchema)); // bool(false)
// 4. 失敗例: 構文的に無効なJSON (末尾にカンマがある)
$invalidSyntaxJson = '{"id": 4, "name": "Dave", "isActive": true,}';
echo "Invalid Syntax JSON: ";
var_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
を指定して連想配列にすることが非常に重要です。この指定がないとオブジェクトが返され、後続のキー存在チェックが正しく機能しません。また、この検証関数はネストしたオブジェクトや、あってもなくてもよいオプションのキーには対応していません。スキーマに定義されていない余分なキーが含まれていても検証を通過するため、より厳密な仕様が求められる場合は、コードの追加修正や専用ライブラリの利用を検討する必要があります。