frontlayer/json-schema

此软件包的最新版本(dev-master)没有可用的许可证信息。

JSON Schema 验证器

dev-master 2019-08-20 18:55 UTC

This package is auto-updated.

Last update: 2024-09-21 20:56:30 UTC


README

Build Status Latest Stable Version Total Downloads

JSON 结构与给定的 Schema 进行验证。

支持所有官方的 JSON Schema Draft 7 测试

(没有针对大数字的两个测试,因为 PHP 无法验证它们)

简介

  • PHP 严格代码
    • 使用 stdObjects 而不是关联数组
    • 严格模式 declare(strict_types=1);
    • 返回类型 : void, : bool, : string, ...
    • 方法参数类型 bool $isSomething, string $someValue
  • 超过 2300 个测试
  • 使用 官方 OpenAPI Schema (Draft 4)PetStore 规范 对 OpenAPI 进行测试
  • 支持数据类型转换,例如查询/POST/URL 路径中的数据
  • 注册自定义格式
  • 在复杂结构中应用默认值,如 if/then/elseoneOf/allOf/anyOf
  • 代码整洁
  • 文档齐全

待完成事项 @todo

  • 完成:refRemote 和一些 ref 的测试
  • 为 composer 添加版本
  • 语法正确的注释和异常

安装

Composer

composer require frontlayer/json-schema

如何开始

简单示例

$data = 10;
$jsonSchema = '{
    "type": "integer",
    "minimum": 10
}';

$schema = new \FrontLayer\JsonSchema\Schema(json_decode($jsonSchema));
$validator = new \FrontLayer\JsonSchema\Validator();

try {
    $validator->validate($data, $schema);
} catch (\Exception $e) {
    print 'FAIL: ' . $e->getMessage();
    die(1);
}

print 'SUCCESS';

类型转换

$data = (object)[
    'stringTest' => 123, // Integer > String
    'jsonStringTest' => '{"key": "value"}', // JSON string > PHP Object
    'integerTest' => '456', // String > Integer
    'numberTest' => '10.10', // String > Float/Double
    'booleanTest' => 'TRUE' // String > Boolean
];

$jsonSchema = (object)[
    'type' => 'object',
    'properties' => (object)[
        'stringTest' => (object)[
            'type' => 'string'
        ],
        'jsonStringTest' => (object)[
            'type' => 'object'
        ],
        'integerTest' => (object)[
            'type' => 'integer'
        ],
        'numberTest' => (object)[
            'type' => 'number'
        ],
        'booleanTest' => (object)[
            'type' => 'boolean'
        ]
    ]
];

$schema = new \FrontLayer\JsonSchema\Schema($jsonSchema);
$validator = new \FrontLayer\JsonSchema\Validator(\FrontLayer\JsonSchema\Validator::MODE_CAST);
$newData = $validator->validate($data, $schema);
var_dump($newData);

注册自定义格式

use \FrontLayer\JsonSchema\Schema;
use \FrontLayer\JsonSchema\Validator;
use \FrontLayer\JsonSchema\ValidationException;
use \FrontLayer\JsonSchema\SchemaException;

// Prepare data & schema
$data = '507f191e810c19729de860ea';

$jsonSchema = (object)[
    'type' => 'string',
    'format' => 'objectId'
];

// Initialize
$schema = new Schema($jsonSchema);
$validator = new Validator(Validator::MODE_CAST);

// Register new format
$validator->registerFormat('objectId', function (string $input): bool {
    return (bool)preg_match('/^[a-f\d]{24}$/i', $input);
});

// Validate and catch the problems
try {
    $validator->validate($data, $schema);
} catch (ValidationException $e) {
    print 'Validation Problem: ' . $e->getMessage();
    die(1);
} catch (SchemaException $e) {
    print 'Schema Structure Problem: ' . $e->getMessage();
    die(1);
} catch (\Exception $e) {
    print 'General Problem: ' . $e->getMessage();
    die(1);
}

print 'SUCCESS';

直接从不同情况下的默认值构建整个周

$data = (object)[
    'week' => (object)[]
];

$jsonSchema = '
{
    "properties": {
        "week": {
            "properties": {
                "day1": {
                    "default": "Monday"
                }
            },
            "if": {
                "type": "object"
            },
            "then": {
                "default": {
                    "day2": "Thursday"
                }
            },
            "allOf": [
                {
                    "properties": {
                        "day2": {
                            "const": "Thursday"
                        }
                    },
                    "default": {
                        "day3": "Wednesday"
                    }
                },
                {
                    "properties": {
                        "day3": {
                            "const": "Wednesday"
                        }
                    },
                    "default": {
                        "day4": "Tuesday"
                    }
                }
            ],
            "anyOf": [
                {
                    "properties": {
                        "day4": {
                            "const": "Fail"
                        }
                    },
                    "default": {
                        "day5": "Fail"
                    }
                },
                {
                    "properties": {
                        "day4": {
                            "const": "Tuesday"
                        }
                    },
                    "default": {
                        "day5": "Friday",
                        "day6": "Saturday"
                    }
                }
            ],
            "oneOf": [
                {
                    "type": "boolean",
                    "default": {
                        "day3": "Fail"
                    }
                },
                {
                    "properties": {
                        "day6": {
                            "const": "Saturday"
                        }
                    },
                    "default": {
                        "day7": "Sunday"
                    }
                }
            ]
        }
    }
}
';

$schema = new \FrontLayer\JsonSchema\Schema(json_decode($jsonSchema));
$validator = new \FrontLayer\JsonSchema\Validator(\FrontLayer\JsonSchema\Validator::MODE_APPLY_DEFAULTS);

$newData = (array)$validator->validate($data, $schema)->week;
ksort($newData);
var_dump(implode('; ', $newData)); // Monday;Thursday;Wednesday;Tuesday;Friday;Saturday;Sunday

验证模式

您可以使用位运算符 ^ 组合多个标志

$validator->validate($data, $schema, Validator::MODE_CAST ^ Validator::MODE_REMOVE_ADDITIONALS ^ Validator::MODE_APPLY_DEFAULTS)

使用所有官方和自定义测试测试项目

composer run test