darsyn / unboxer
简单的工具,将复杂的数据结构(对象)转换为原生数据类型,适合编码成JSON、YAML等格式。
0.3.1
2021-03-09 12:28 UTC
Requires
- php: >=7.1
Requires (Dev)
- ext-json: *
- doctrine/collections: ^1.0 | ^2.0
This package is auto-updated.
Last update: 2024-09-09 20:10:04 UTC
README
简单的工具,将复杂的数据结构(对象)转换为原生数据类型,适合编码(例如,JSON)。
文档
行为准则
本项目包含并遵守贡献者公约作为行为准则。
支持的类型
此库将所有标量和null值按原样返回,并递归处理所有数组(和stdClass
)类型。
当此库遇到已知类型的对象实例时,它将尝试通过使用特定方法的返回值来转换它。此库默认支持的对象类型包括
- 日期(实现
DateTimeInterface
的对象),根据RFC3339转换为字符串(例如,2019-02-05T12:15:32+00:00
)。 - 时区(实现
DateTimeZone
的对象),结果是包含时区名称的字符串(例如,America/Vancouver
)。 - 异常和错误(实现
Throwable
的对象),结果是包含异常信息的字符串。 - JSON(实现
JsonSerializable
的对象),结果是库递归遍历返回的JSON数据。 - Doctrine集合(实现
Collection
接口的对象),结果是库遍历集合中的每个项目。
此外,任何用户空间对象都可以实现UnboxableInterface
。类似于JsonSerializable::jsonSerialize()
方法,__unbox
方法可以返回表示其内部状态的任何内容。建议按原样返回可解包的对象,因为从UnboxableInterface::__unbox
返回的任何内容都将递归遍历。
简要示例
<?php declare(strict_types=1); use Darsyn\Unboxer\Unboxer; use Darsyn\Unboxer\UnboxableInterface; use Darsyn\Unboxer\UnboxingException; class Group implements UnboxableInterface { public function __construct( private string $name ) {} public function __unbox() { return $this->name; } } class Options implements \JsonSerializable { public function __construct( private bool $active, private bool $verified, private \DateTimeZone $timezone ) {} public function jsonSerialize() { return [ 'active' => $this->active, 'verified' => $this->verified, 'tz' => $this->timezone, ]; } } class Member implements UnboxableInterface { private ArrayCollection $groups; public function __construct( private int $id, private string $username, array $groups = [], private ?Options $options = null ) { $this->groups = new ArrayCollection($groups); } public function __unbox() { return [ // Scalars are used as-is. 'id' => $this->id, 'username' => $this->username, // Objects of known types are returned as-is, but recursively iterated over. 'groups' => $this->groups, // JSON-serializable objects are never actually run through json_encode(). 'options' => $this->options ?: [], ]; } } $member = new Member(123, 'dr-evil', [ new Group('admin'), new Group('moderator'), new Group('sharks-with-lasers'), ], new Options(true, false, new \DateTimeZone('America/Vancouver'))); try { $output = (new Unboxer)->unbox($member); var_dump($output); } catch (UnboxingException $e) { echo $e->getMessage(); }
使用var_dump
变量$output
的结果是
array(4) {
'id' =>
int(123)
'username' =>
string(7) "dr-evil"
'groups' =>
array(3) {
[0] =>
string(5) "admin"
[1] =>
string(9) "moderator"
[2] =>
string(18) "sharks-with-lasers"
}
'options' =>
array(3) {
'active' =>
bool(true)
'verified' =>
bool(false)
'tz' =>
string(17) "America/Vancouver"
}
}
注意,返回多个嵌套的可解包对象会导致输出折叠为单个值
<?php declare(strict_types=1); use Darsyn\Unboxer\Unboxer; use Darsyn\Unboxer\UnboxableInterface; use Darsyn\Unboxer\UnboxingException; $data = new class implements UnboxableInterface { public function __unbox() { return new class implements UnboxableInterface { public function __unbox() { return new class implements UnboxableInterface { public function __unbox() { return new \RuntimeException('Error Message'); } }; } }; } }; try { $output = (new Unboxer)->unbox($data); var_dump($output); } catch (UnboxingException $e) { echo $e->getMessage(); }
string(13) "Error Message"
扩展
可以通过扩展Unboxer
并重写getKnownDataTypes
方法来添加额外的已知对象类型。对于每个已知对象类型,可以指定一个闭包或一个数组,指定在对象上调用哪个方法
<?php declare(strict_types=1); use Darsyn\Unboxer\Unboxer; class MyUnboxer extends Unboxer { protected function getKnownDataMethods(): iterable { // Don't forget to return the known data methods defined in the original, parent Unboxer. // The parent returns an array, but any iterable is acceptable. yield from parent::getKnownDataMethods(); // Config array example. // Must be in the format ['methodToCall', ['optional', 'arguments', 'array']]. yield \DateTimeInterface::class => ['format', [\DateTimeInterface::RFC3339]]; // Closure example. yield \DateTimeInterface::class => function (\DateTimeInterface $date): string { return $date->format(\DateTimeInterface::RFC3339); }; } }
默认情况下,解包器将具有__toString()
魔法方法的任何对象转换为字符串。要关闭此功能,扩展Unboxer
并重写类常量STRINGIFY_OBJECTS
。
<?php declare(strict_types=1); use Darsyn\Unboxer\Unboxer; class MyUnboxer extends Unboxer { public const STRINGIFY_OBJECTS = false; }
许可证
请参阅此存储库中包含的单独的许可证文件,其中包含完整的MIT许可证副本,本项目受此许可证许可。
作者
如果您做出贡献(提交拉取请求),请别忘了在此处添加您的名字!