helmich / schema2class
从JSON schema定义构建PHP类
资助包维护!
martin-helmich
donate.helmich.me
Requires
- php: ^8.2
- ext-json: *
- composer/semver: ^3.0
- justinrainbow/json-schema: ^6.0
- laminas/laminas-code: ^4.12
- symfony/console: ~3.0|~4.0|~5.0|~6.0|~7.0
- symfony/yaml: ~3.0|~4.0|~5.0|~6.0|~7.0
Requires (Dev)
- phpspec/prophecy: ^1.17
- phpspec/prophecy-phpunit: ^2.0
- phpunit/phpunit: ^10.5
- vimeo/psalm: ^5.12
- dev-master
- v3.3.4
- v3.3.3
- v3.3.2
- v3.3.1
- v3.3.0
- v3.2.0
- v3.1.3
- v3.1.2
- v3.1.1
- v3.1.0
- v3.0.1
- v3.0.0
- v2.1.3
- v2.1.2
- v2.1.1
- v2.1.0
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- v1.0.1
- v1.0.0
- dev-bugfix/default-values-unset
- dev-bugfix/duplicate-property-names
- dev-refact/cleanup-2024
- dev-dependabot/composer/phpunit/phpunit-tw-11.2
- dev-feature-custom-validator
- dev-feature/custom-validator
- dev-task/bump-deps
- dev-bugfix-enum-case-int-prefix
- dev-default-as-optional
- dev-feature/dynamic-objects
This package is auto-updated.
Last update: 2024-09-04 14:54:27 UTC
README
自动从JSON schemas构建PHP类。
示例
考虑一个简单的JSON schema(讽刺的是以YAML格式存储),存储在文件example.yaml
中
required: - givenName - familyName properties: givenName: type: string familyName: type: string hobbies: type: array items: type: string location: properties: country: type: string city: type: string
使用此转换器,您可以自动从这个schema生成带有访问器和转换函数的PHP类
$ vendor/bin/s2c generate:fromschema --class User ./example.yaml src/Target
此命令将自动尝试从您的composer.json
文件中推断PHP目标命名空间,并自动创建相应的PHP类
$ find src/Target src/Target src/Target/User.php src/Target/UserLocation.php
然后,在您的代码中使用这些类
$userData = json_decode("user.json", true); $user = \MyNamespace\Target\User::buildFromInput($userData); echo "Hello, " . $user->getGivenName() . "\n";
兼容性
此工具需要PHP 8.2或更高版本才能运行。
生成的代码可以向后兼容到PHP 5.6。使用--target-php
标志设置生成的代码应兼容的PHP版本。当使用配置文件时,使用targetPHPVersion
属性。
创建结果
生成的类具有以下功能
- 类命名空间可以通过命令行(
--target-namespace
)、规范文件(targetNamespace
)指定。如果没有指定,生成器将检查您的项目的composer.json
,查找任何PSR-4配置,并从中推断命名空间。 - 主对象的名称由命令行(
--class
)或规范文件定义。 - 子对象的名称取自属性名称。
- 数组项后缀为'Item'。
OneOf
选项后缀为'AlternativeX',其中X
是递增的整数。- 构造函数具有对schema中所有必需属性的参数。
- 所有属性都是私有的,有getter方法进行访问,并具有显式的返回值类型声明(在PHP5模式下,仅使用PHPDoc)。
- 静态函数
buildFromInput(array $data)
接受一个数组(使用json_decode('{}', true)
),根据schema进行验证,并创建完整的对象树作为返回值。不需要额外的映射步骤。 - 函数
toJson()
返回一个用于json_encode()
的纯数组。 - 通过使用
withX()
(或用于可选值的withoutX()
)不可变地写入任何对象的属性。这将返回一个包含值更改的新实例。
以下是一个从上述schema中删除所有注释的简短版本示例,仅包含城市位置(国家行为相同,但名称不同)
class UserLocation { private static array $schema = array( 'properties' => array( 'city' => array( 'type' => 'string', ), ), ); private ?string $country = null; private ?string $city = null; public function __construct() { } public function getCity() : ?string { return $this->city; } public function withCity(string $city) : self { $validator = new \JsonSchema\Validator(); $validator->validate($city, static::$schema['properties']['city']); if (!$validator->isValid()) { throw new \InvalidArgumentException($validator->getErrors()[0]['message']); } $clone = clone $this; $clone->city = $city; return $clone; } public function withoutCity() : self { $clone = clone $this; unset($clone->city); return $clone; } public static function buildFromInput(array $input) : UserLocation { static::validateInput($input); $city = null; if (isset($input['city'])) { $city = $input['city']; } $obj = new static(); $obj->city = $city; return $obj; } public function toJson() : array { $output = []; if (isset($this->city)) { $output['city'] = $this->city; } return $output; } public static function validateInput(array $input, bool $return = false) : bool { $validator = new \JsonSchema\Validator(); $validator->validate($input, static::$schema); if (!$validator->isValid() && !$return) { $errors = array_map(function($e) { return $e["property"] . ": " . $e["message"]; }, $validator->getErrors()); throw new \InvalidArgumentException(join(", ", $errors)); } return $validator->isValid(); } public function __clone() { } }
安装
使用Composer进行安装
$ composer require --dev helmich/schema2class
使用配置文件
在许多项目中,您可能希望将不断发展的JSON schema与生成的PHP类持续同步。为此,S2C允许您创建一个配置文件.s2c.yaml
,该文件存储最常用的转换选项
targetPHPVersion: "7.4" files: - input: src/Spec/Spec.yaml className: Specification targetDirectory: src/Spec
您可以将本地配置存储在此yaml文件中,并通过调用启动生成过程
s2c generate:fromspec
这将扫描当前目录中的.s2c.yaml
并使用其参数。如果您需要为多个schema提供不同的文件,您可以提供配置文件作为参数。