sav / hydrator-creator
通过类构造函数进行对象注水
Requires
- php: ^8.1
Requires (Dev)
- ergebnis/composer-normalize: ^2.31
- friendsofphp/php-cs-fixer: ^3.17.0
- phpunit/phpunit: ^10.1.3
- psalm/plugin-phpunit: ^0.18.4
- vimeo/psalm: ^5.12.0
This package is auto-updated.
Last update: 2024-09-27 08:25:22 UTC
README
该库旨在通过类构造函数进行对象注水。此外,借助可扩展属性,您还可以添加自己的数据提取器、修改器和验证器。该属性可以应用于类或参数。
安装
可以通过composer安装此包
composer require sav/hydrator-creator
注意:当前版本的这个包仅支持PHP 8.1以上。
用法
use Sav\Hydrator\Hydrator; final class User { public readonly string $email; public function __construct( string $email, public readonly string $name ) { $this->email = strtolower($email); } } $data = [ 'email' => 'Test@mail.com', 'name' => 'Sam', ]; $user = Hydrator::init()->hydrate(User::class, $data); var_dump($user);
结果
object(User) { ["email"]=> string(13) "test@mail.com" ["name"]=> string(3) "Sam" }
如果属性不是标量类型,而是允许其他对象的类,它也会自动转换。如果一个类在构造函数中使用了参数,它将自动传递给构造函数,无需指定确切名称。这允许将数据转换为简单的ValueObjects。
use Sav\Hydrator\Hydrator; final class Item { public function __construct( public readonly int $id, public readonly string $name, ) { } } final class PriceValueObject { public function __construct( private readonly float $value, ) { } public function getValue(): float { return $this->value; } } final class OrderItem { public function __construct( public readonly Item $product, public readonly PriceValueObject $cost, ) { } } $data = [ 'product' => ['id' => 1, 'name' => 'phone'], 'cost' => 10012.23, ]; $orderItem = Hydrator::init()->hydrate(OrderItem::class, $data); var_dump($orderItem);
结果
object(OrderItem) { ["product"]=> object(Item) { ["id"]=> int(1) ["name"]=> string(5) "phone" } ["cost"]=> object(PriceValueObject) { ["value":"PriceValueObject":private]=> float(10012.23) } }
对象数组
如果您有一组特定类的对象数组,那么您必须指定ArrayOfObjects属性,将其传递给您需要的类以获取元素。
示例
use Sav\Hydrator\Hydrator; use Sav\Hydrator\Attribute\ArrayMap\ArrayOfObjects; class Product { public function __construct( public readonly int $id, public readonly DateTimeImmutable $dateCreate, ) { } } class Products { public function __construct( #[ArrayOfObjects(Product::class)] public readonly array $products ) { } } $data = [ 'products' => [ ['id' => 1, 'dateCreate' => '2023-01-01'], ['id' => 2, 'dateCreate' => '2023-01-02'], ], ]; $products = Hydrator::init()->hydrate(Products::class, $data); var_dump($products);
结果
object(Products) { ["products"]=> array(2) { [0]=> object(Product) { ["id"]=> int(1) ["dateCreate"]=> object(DateTimeImmutable) { ["date"]=> string(26) "2023-01-01 00:00:00.000000" ["timezone_type"]=> int(0) ["timezone"]=> string(3) "UTC" } } [1]=>object(Product) { ["id"]=> int(2) ["dateCreate"]=> object(DateTimeImmutable) { ["date"]=> string(26) "2023-01-02 00:00:00.000000" ["timezone_type"]=> int(0) ["timezone"]=> string(3) "UTC" } } } }
字段别名
可以为属性设置各种可能的别名,这些别名也将搜索数据源。
use Sav\Hydrator\Hydrator; use Sav\Hydrator\Attribute\ValueExtractor\Alias; class User { public function __construct( private readonly int $id, #[Alias('personalPhone')] private readonly string $phone, ) { } }
默认值
使用DefaultValue属性,您可以设置参数的默认值。您也可以使用标准的PHP语法设置默认值。
use Sav\Hydrator\Hydrator; use Sav\Hydrator\Attribute\ValueModifier\DefaultValue; class User { public function __construct( public readonly int $id, #[DefaultValue(new DateTimeImmutable('2023-01-03'))] public readonly DateTimeImmutable $dateCreate, #[DefaultValue(100, applyForEmpty: true)] public readonly int $balance, public readonly int $limit = 30, ) { } } $user = Hydrator::init()->hydrate(User::class, ['id' => 1, 'balance' => 0]); var_dump($user);
结果
object(User) { ["id"]=> int(1) ["dateCreate"]=> object(DateTimeImmutable) { ["date"]=> string(26) "2023-01-03 00:00:00.000000" ["timezone_type"]=> int(0) ["timezone"]=> string(3) "UTC" } ["balance"]=> int(100) ["limit"]=> int(30) }
参数的必填值
该属性指定输入数据中是否需要参数值。该属性可以应用于类或参数。
use Sav\Hydrator\Hydrator; use Sav\Hydrator\Attribute\RequiredKeyValue; #[RequiredKeyValue] class User { public function __construct( public readonly ?int $id, public readonly int $balance = 3, ) { } } try { $user = Hydrator::init()->hydrate(User::class, ['id' => 1]); } catch(HydratorException $e) { echo $e->getMessage(); }
结果
balance: Value not exist.
非空验证器
NotEmpty属性允许检查参数的完整性。它只检查参数是否被分配了值,并且不是null。如果检查失败,将抛出异常。
use Sav\Hydrator\Hydrator; use Sav\Hydrator\Attribute\ValueValidator\NotEmpty; class User { public function __construct( public readonly int $id, #[NotEmpty] public readonly int $balance, ) { } } try { $user = Hydrator::init()->hydrate(User::class, ['id' => 1, 'balance' => 0]); } catch(HydratorException $e) { echo $e->getMessage(); }
结果
balance: Value is empty.
自定义属性
要扩展功能,您可以编写自己的属性,这些属性根据其目的实现特定的接口。
-
Sav\Hydrator\Attribute\ValueExtractor
用于更改在输入数据中搜索参数值的方式。别名属性是此类属性的示例。 -
\Sav\Hydrator\Attribute\ValueModifier
用于转换找到的值。DefaultValue属性可以是此类属性的一个例子。 -
\Sav\Hydrator\Attribute\ValueValidator
用于检查提取和修改后的数据。NotEmpty属性是验证空值的一个示例。 -
\Sav\Hydrator\Attribute\ArrayMap
用于定义具有特定键的值的解释类型。ArrayOfObjects属性是一个示例,它将数组中的每个元素解释为指定类的值。