當前位置: 妍妍網 > 碼農

PHP使用JSON Schema進行JSON數據驗證和型別檢查

2024-04-03碼農

什麽是JSON Schema?

JSON Schema是一個用於描述和驗證JSON數據結構的規範。JSON Schema可以驗證JSON數據是否符合指定的模式、型別和約束條件,同時還可以提供數據文件化的作用。

JSON Schema的結構

JSON Schema結構分為三個部份 JSON Schema結構分為三個部份:

關鍵字

這是JSON Schema中最重要的部份,它定義了用於數據驗證的規則和條件,例如: required type properties minimum 等。可以在規範中檢視完整的關鍵字列表。

架構例項

架構例項是一個JSON檔或物件,它描述了要驗證的數據結構,包括數據型別、內容名稱、數值範圍等。

後設資料

後設資料是用於描述JSON Schema本身的數據,例如: title description id 等。這些後設資料不會被用於驗證JSON數據,但是它們對於理解Schema非常重要。

使用 JSON Schema

justinrainbow/json-schema 是一個PHP實作,用於根據給定的 Schema 驗證 JSON 結構,支持 草案3 草案4 Schemas 。可能不支持較新草稿的功能。請參閱所有版本的表格,以獲得所有現有草稿的概述。

安裝

composer require justinrainbow/json-schema

基本用法

<?php
$data = json_decode(file_get_contents('data.json'));
// Validate
$validator = new JsonSchema\Validator;
$validator->validate($data, (object)['$ref' => 'file://' . realpath('schema.json')]);
if ($validator->isValid()) {
echo"The supplied JSON validates against the schema.\n";
else {
echo"JSON does not validate. Violations:\n";
foreach ($validator->getErrors() as $error) {
printf("[%s] %s\n"$error['property'], $error['message']);
}
}

型別強制

如果你正在驗證透過HTTP傳遞給你的應用程式的數據,你可以將字串和布爾值轉換為你的模式定義的預期型別:

<?php
use JsonSchema\SchemaStorage;
use JsonSchema\Validator;
use JsonSchema\Constraints\Factory;
use JsonSchema\Constraints\Constraint;
$request = (object)[
'processRefund'=>"true",
'refundAmount'=>"17"
];
$validator->validate(
$request, (object) [
"type"=>"object",
"properties"=>(object)[
"processRefund"=>(object)[
"type"=>"boolean"
],
"refundAmount"=>(object)[
"type"=>"number"
]
]
],
Constraint::CHECK_MODE_COERCE_TYPES
); // validates!
is_bool($request->processRefund); // true
is_int($request->refundAmount); // true


也可以使用速記方法:

$validator->coerce($request$schema);
// equivalent to $validator->validate($data$schema, Constraint::CHECK_MODE_COERCE_TYPES);

預設值

如果您的架構包含預設值,則可以在驗證期間自動套用這些值:

<?php
use JsonSchema\Validator;
use JsonSchema\Constraints\Constraint;
$request = (object)[
'refundAmount'=>17
];
$validator = new Validator();
$validator->validate(
$request,
(object)[
"type"=>"object",
"properties"=>(object)[
"processRefund"=>(object)[
"type"=>"boolean",
"default"=>true
]
]
],
Constraint::CHECK_MODE_APPLY_DEFAULTS
); //validates, and sets defaults for missing properties
is_bool($request->processRefund); // true
$request->processRefund; // true



使用行內參照

<?php
use JsonSchema\SchemaStorage;
use JsonSchema\Validator;
use JsonSchema\Constraints\Factory;
$jsonSchema = <<<'JSON'
{
"type""object",
"properties": {
"data": {
"oneOf": [
"$ref""#/definitions/integerData" },
"$ref""#/definitions/stringData" }
]
}
},
"required": ["data"],
"definitions": {
"integerData" : {
"type""integer",
"minimum" : 0
},
"stringData" : {
"type""string"
}
}
}
JSON;
// Schema must be decoded before it can be used for validation
$jsonSchemaObject = json_decode($jsonSchema);
// The SchemaStorage can resolve references, loading additional schemas from file as needed, etc.
$schemaStorage = new SchemaStorage();
// This does two things:
// 1) Mutates $jsonSchemaObject to normalize the references (to file://mySchema#/definitions/integerData, etc)
// 2) Tells $schemaStorage that references to file://mySchema... should be resolved by looking in$jsonSchemaObject
$schemaStorage->addSchema('file://mySchema'$jsonSchemaObject);
// Provide $schemaStorage to the Validator so that references can be resolved during validation
$jsonValidator = new Validator(new Factory($schemaStorage));
// JSON must be decoded before it can be validated
$jsonToValidateObject = json_decode('{"data":123}');
// Do validation (use isValid() and getErrors() to check the result)
$jsonValidator->validate($jsonToValidateObject$jsonSchemaObject);






配置選項

有許多標誌可用於改變驗證器的行為。這些可以作為第三個參數傳遞給 Validator::validate() ,或者如果您希望在多個 validate() 呼叫中持久化它們,則可以作為第三個參數提供給 Factory::__construct()

Flag Description
Constraint::CHECK_MODE_NORMAL 在「正常」模式下執行-這是預設設定
Constraint::CHECK_MODE_TYPE_CAST 為關聯陣列和物件啟用模糊型別檢查
Constraint::CHECK_MODE_COERCE_TYPES 盡可能轉換數據型別以匹配架構
Constraint::CHECK_MODE_EARLY_COERCE 盡快套用型別強制
Constraint::CHECK_MODE_APPLY_DEFAULTS 如果未設定,則套用架構中的預設值
Constraint::CHECK_MODE_ONLY_REQUIRED_DEFAULTS 套用預設值時,僅設定必需的值
Constraint::CHECK_MODE_EXCEPTIONS 如果驗證失敗,立即引發異常
Constraint::CHECK_MODE_DISABLE_FORMAT 不驗證「格式」約束
Constraint::CHECK_MODE_VALIDATE_SCHEMA 對架構以及提供的文件進行重新配置

請註意,使用 CHECK_MODE_COERCE_TYPES CHECK_MODE_APPLY_DEFAULTS 將修改您的原始數據。

CHECK_MODE_EARLY_COERCE 沒有效果,除非與 CHECK_MODE_COERCE_TYPES 結合使用。如果啟用,驗證器將使用(並強制)它遇到的第一個相容型別,即使模式定義了另一個直接匹配且不需要強制的型別。

執行測試

composer test# run all unit tests
composer testOnly Test class # run specific unit test class
composer testOnly Test class::testMethod # run specific unit test method
composer style-check # check code style for errors
composer style-fix # automatically fix code style errors

總結

使用JSON Schema能夠讓我們更輕易地對數據進行約束和驗證,使在開發API時更加安心。在PHP中使用JSON Schema非常簡單,只需要將數據和模式傳入驗證器中即可。希望本文能夠幫助你更好地理解JSON Schema並套用於實際開發中。