42sol / json-decoder
JsonDecoder实现,允许您将JSON数据转换为PHP类对象
Requires
- php: ^8.0
- php-di/phpdoc-reader: ^2.1
Requires (Dev)
- laravel/pint: ^1.5 | ^1.6
- pestphp/pest: ^1.22
- phpstan/phpstan: ^1.10
This package is auto-updated.
Last update: 2024-09-25 13:09:27 UTC
README
PHP的JsonDecoder
此包包含一个JsonDecoder实现,允许您将JSON数据转换为php类对象,而不仅仅是stdclass
。
安装
您可以通过composer安装此包
composer require karriere/json-decoder
使用方法
默认情况下,解码器会遍历所有定义的JSON字段,并尝试将这些值设置在给定的类类型实例上。这种行为的变化允许在像Laravel的Eloquent模型这样的使用__get
和__set
魔术方法的类上使用json-decoder
。
如果找到一个与JSON字段同名的属性或为JSON字段定义了显式的绑定
,则将其解码到定义的位置。否则,将创建并分配属性(如果您使用的是PHP 8.2,则需要#[AllowDynamicProperties]
属性)。
JsonDecoder
类可以接收一个名为shouldAutoCase
的参数。如果设置为true,它将尝试自动从snake-case或kebab-case找到camel-case版本,如果没有为字段注册其他绑定,并且将使用AliasBinding
(如果找到其中一个变体)。
简单示例
假设您有一个看起来是这样的Person
类
#[AllowDynamicProperties] class Person { public int $id; public string $name; public ?string $lastname = ''; }
以下代码将把给定的JSON数据转换为Person
的一个实例。
$jsonDecoder = new JsonDecoder(); $jsonData = '{"id": 1, "name": "John Doe", "lastname": null, "dynamicProperty": "foo"}'; $person = $jsonDecoder->decode($jsonData, Person::class);
请注意,由于PHP 8.2.动态属性已被弃用。因此,如果您仍然希望使用这些动态属性,您必须将PHP属性AllowDynamicProperties
添加到您的类中。如果您使用的是PHP 8.2.(及以上版本)并且没有使用AllowDynamicProperties
属性,则所有动态属性都将被忽略。
更复杂的使用案例
让我们以前面的例子为基础,添加一个名为address的属性。此地址字段应包含一个Address
实例。从版本4开始,您可以使用引入的scanAndRegister
方法自动根据类注释生成转换器。从版本5开始,您还可以使用属性类型而不是类注释。
class Person { public int $id; public string $name; /** * @var Address */ public $address; public ?Address $typedAddress = null; }
对于此类定义,我们可以如下解码JSON数据
$jsonDecoder = new JsonDecoder(); $jsonDecoder->scanAndRegister(Person::class); $jsonData = '{"id": 1, "name": "John Doe", "address": {"street": "Samplestreet", "city": "Samplecity"}, , "typedAddress": {"street": "Samplestreet", "city": "Samplecity"}}'; $person = $jsonDecoder->decode($jsonData, Person::class);
定义一个转换器
如果您不使用注释或需要一个更灵活的Transformer
,您还可以创建一个自定义转换器。让我们看看没有注释的先前的例子。
class Person { public int $id; public string $name; public mixed $address; }
要能够将地址数据转换为Address
类对象,您需要为Person
定义一个转换器
转换器接口定义了两个方法
- register:在这里,您注册您的字段、数组、别名和回调绑定
- transforms:给出完全限定的类名,例如:您的命名空间\类
class PersonTransformer implements Transformer { public function register(ClassBindings $classBindings) { $classBindings->register(new FieldBinding('address', 'address', Address::class)); } public function transforms() { return Person::class; } }
注册转换器后,JsonDecoder
将使用定义的转换器
$jsonDecoder = new JsonDecoder(); $jsonDecoder->register(new PersonTransformer()); $jsonData = '{"id": 1, "name": "John Doe"}'; $person = $jsonDecoder->decode($jsonData, Person::class);
处理私有和受保护属性
从版本4开始,JsonDecoder
类将自动处理private
和protected
属性。
转换元素数组
如果您的JSON在根级别包含元素数组,您可以使用decodeMultiple
方法将JSON数据转换为类类型对象的数组。
$jsonDecoder = new JsonDecoder(); $jsonData = '[{"id": 1, "name": "John Doe"}, {"id": 2, "name": "Jane Doe"}]'; $personArray = $jsonDecoder->decodeMultiple($jsonData, Person::class);
文档
转换器绑定
以下Binding
实现可用:
FieldBinding
为给定类型定义JSON字段到属性的绑定。
签名
new FieldBinding(string $property, ?string $jsonField = null, ?string $type = null, bool $isRequired = false);
这定义了将属性$property
映射到类型为$type
的类实例,并在$jsonField
中包含数据的字段映射。
ArrayBinding
为给定类型定义数组字段绑定。
签名
new ArrayBinding(string $property, ?string $jsonField = null, ?string $type = null, bool $isRequired = false);
这定义了将属性$property
映射到类型为$type
的类实例数组,并在$jsonField
中包含数据的字段映射。
AliasBinding
定义JSON字段到属性的绑定。
签名
new AliasBinding(string $property, ?string $jsonField = null, bool $isRequired = false);
DateTimeBinding
定义JSON字段到属性的绑定,并将给定的字符串转换为DateTime
实例。
签名
new DateTimeBinding(string $property, ?string $jsonField = null, bool $isRequired = false, $dateTimeFormat = DateTime::ATOM);
CallbackBinding
定义一个属性绑定,该绑定获取回调结果集作为其值。
签名
new CallbackBinding(string $property, private Closure $callback);
许可证
Apache License 2.0 请参阅LICENSE获取更多信息。