hamlet-framework / json-mapper
Json 数据绑定
0.0.5
2021-02-16 09:55 UTC
Requires
- php: ^7 || ^8
- hamlet-framework/type: >= 0.2.0
Requires (Dev)
- ext-json: *
- php-parallel-lint/php-parallel-lint: @stable
- phpunit/phpunit: ^6 || ^7 || ^8
- squizlabs/php_codesniffer: @stable
- symfony/polyfill-mbstring: <=1.20.0
- vimeo/psalm: @stable
README
快速概要
- Psalm 类型规范,包括对象数组、联合类型、关联数组等。
- PHP-Parser 用于解析 FQCN
- 默认使用反射
- 可重用的代码配置
- 通过子类型解析器支持多态
- 级联配置选项用于子树解析
- 类型安全:Psalm 将知道
JsonMapper::map(_list(_class(User::class)), ...)
返回list<User>
。 - 抛出类型转换异常
作为一个开始,将以下 JSON 结构
[ { "name": "Yuri" }, { "name": "Oleg", "email": "oleg@example.com", "address": { "city": "Vologda" } } ]
映射到以下类层次结构
<?php class User { /** @var string */ private $name; /** @var string|null */ private $email; /** @var Address|null */ private $address; } class Address { /** @var string */ private $city; }
使用
<?php $users = JsonMapper::map( _list(_class(User::class)), json_decode($data) );
该库使用 hamlet-framework/type 库进行类型规范。
配置选项
JsonMapper::map
的第三个参数是 JsonMapperConfiguration
,用于自定义映射过程。
Json 属性
<?php $configuration ->withDefaultValue(User::class, 'name', 'unknown') ->withJsonName(User::class, 'homeAddress', 'home_address', 'homeaddress') ->ignoreUnknown(User::class);
使用 Setters
<?php $configuaration ->withPropertySetters(User::class) ->withPropertySetter(User::class, 'homeAddress', 'updateHomeAddress');
使用 Converter
<?php class User { /** @var DateTimeImmutable */ private $time; /** @var array<string,string> */ private $preferences; /** @var string|null */ private $email; } $json = ' { "time": 1593479541, "preferences": "{\"timeZone\":\"Russia/Moscow\"}", "email": "_.oO000_" } '; $configuration ->withConverter(User::class, 'time', function (int $unixtime) { return DateTimeImmutable::createFomFormat('U', (string) $unixtime); }) ->withConverter(User::class, 'preferences', function (string $json) { return _map(_string(), _string())->cast(json_decode($json)); }) ->withConverter(self::class, 'email', function ($email) { return filter_var($email, FILTER_VALIDATE_EMAIL) ?: null; }); $user = JsonMapper::map(_class(User::class), json_decode($json), $configuration); $user->preferences['timeZone'] == 'Russia/Moscow'; $user->time instanceof DateTimeImmutable; $user->email === null;
使用 Type Dispatcher
<?php $configuration ->withTypeDispatcher(User::class, function ($properties) { if (isset($properties['name'])) { return NamedUser::class; } else { return AnonymousUser::class; } });
<?php $coniguration ->withTypeDispatcher(User::class, '__resolveType');
使用 JsonMapperAware 接口
如果您想将映射配置保持得与您映射的文件更接近,有一个选项可以实现 JsonMapperAware
接口
<?php class Car implements JsonMapperAware { /** @var string */ protected $make; public function make(): string { return $this->make; } public static function configureJsonMapper(JsonMapperConfiguration $configuration): JsonMapperConfiguration { return $configuration ->withTypeResolver(self::class, function ($properties) { if (array_key_exists('machineGunCapacity', (array) $properties)) { return JamesBondCar::class; } else { return Car::class; } }); } } $cars = JsonMapper::map(_list(_class(Car::class)), json_decode($payload));
待办事项
- 添加对
ignoreUnknown
的支持 - 添加对构造函数方法的支持
- 添加验证器
- 添加带有 psalm 规范的示例