uxf / hydrator
3.44.5
2024-05-30 18:11 UTC
Requires
- php: ^8.3
- nette/php-generator: ^4.0
- phpdocumentor/type-resolver: ^1.7
- thecodingmachine/safe: ^2.0
This package is auto-updated.
Last update: 2024-08-31 00:41:23 UTC
README
最快的PHP对象填充器...
安装
$ composer req uxf/hydrator
配置
// config/packages/uxf.php
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use UXF\Core\Http\Request\NotSet;
return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->extension('uxf_hydrator', [
'ignored_types' => [NotSet::class], // optional
'overwrite' => true, // optional (default %kernel.debug%)
'default_options' => [
'allow_lax_string' => true, // default false
'allow_trim_string' => true, // default false
'allow_fallback' => true, // default false
'xml_mode' => true, // default false
],
]);
};
基本用法
ObjectHydrator
从
class Person
{
public function __construct(
public readonly string $name,
public readonly int $age,
public readonly Sex $sex, // enum
public readonly DateTimeImmutable $createdAt,
public readonly ?string $note = null, // optional
) {
}
}
$hydrator = $container->get(UXF\Hydrator\ObjectHydrator::class);
$data = [
'name' => 'Joe Doe',
'age' => 55,
'sex' => 'MALE',
'createdAt' => '2000-01-02T13:03:01+00:00',
];
// single object
/** @var Person $person */
$person = $this->hydrator->hydrateArray($data, Person::class);
var_dump($person);
/*
Person {
name: "Joe Doe" (string)
age: 55 (int)
sex: Sex::MALE, (enum)
createdAt: "2000-01-02T13:03:01+00:00" (DateTimeImmutable)
}
*/
// array of objects
/** @var Person[] $people */
$people = $this->hydrator->hydrateArrays([$data], Person::class);
异常
try {
$badPerson = $this->hydrator->hydrateArray($badData, Person::class);
} catch (HydratorException $e) {
/** @var array<string, array<string>> $errors */
$errors = $e->errors;
}
选项
- 您可以在包配置中设置
default_options
或作为ObjectHydrator
构造函数参数。 - 或传递带有唯一名称的
Options
参数给hydrateArray
/hydrateArrays
方法。 - 使用唯一的选项名称!!! 相同名称的不同值可能导致意外结果...
allow_lax_string: true
将所有标量或可字符串化对象转换为字符串。
class Test
{
public function __construct(public readonly string $helloWorld) {}
}
$a = ['helloWorld' => new Uuid()]; // Uuid is Stringable
$b = ['helloWorld' => 1]; // 1 => '1'
allow_trim_string: true
修剪所有字符串。
class Test
{
public function __construct(public readonly string $helloWorld) {}
}
$a = ['helloWorld' => ' A ']; // helloWorld => 'A'
allow_fallback: true
使用 FallbackParameterGenerator 作为后备填充器变体。
class Test
{
public function __construct(public readonly mixed $helloWorld) {}
}
$a = ['helloWorld' => ['every value is possible', 1, new DateTime(), ['hello' => 'kitty']];
xml_mode: true
将标量从字符串转换为字符串 + 启用解析空/单项/多项集合
填充器属性
use UXF\Hydrator\Attribute\HydratorProperty;
class Cart
{
public function __construct(
#[HydratorProperty('@id')]
public readonly int $id,
) {
}
}
{
"@id": 1
}
填充器XML
使用 xml_mode: true
,您可以使用 HydratorXml
PHP 属性来处理具有可选 XML 属性的 XML 对象。与 Symfony XmlEncoder 兼容。
use UXF\Hydrator\Attribute\HydratorProperty;
use UXF\Hydrator\Attribute\HydratorXml;
#[HydratorXml('text')] // "text is PHP property name with #"
final readonly class CatDto
{
public function __construct(
#[HydratorProperty('#')]
public string $text,
#[HydratorProperty('@ID')]
public ?int $id = null,
) {
}
}
接受
<cat ID="2">CAT</cat>
或
<cat>CAT</cat>
填充器映射
接口
use UXF\Hydrator\Attribute\HydratorMap;
// interface
#[HydratorMap(property: 'type', matrix: [
'o' => Orienteering::class,
'p' => Paragliding::class,
])]
interface Activity
{
}
// children
class Orienteering implements Activity
{
public function __construct(
public readonly int $card,
) {
}
}
class Paragliding implements Activity
{
public function __construct(
public readonly string $glider,
) {
}
}
// usage
class Club
{
/**
* @param Activity[] $activities
*/
public function __construct(
public readonly array $activities,
public readonly Activity $activity,
) {
}
}
抽象类
use UXF\Hydrator\Attribute\HydratorMap;
// abstract class
#[HydratorMap(property: 'type', matrix: [
'c' => CrossCountrySkiing::class,
'o' => Orienteering::class,
'p' => Paragliding::class,
])]
abstract class Sport
{
}
// children
class CrossCountrySkiing extends Sport
{
public function __construct(
public readonly string $ski,
) {
}
}
class Orienteering extends Sport
{
public function __construct(
public readonly int $card,
) {
}
}
class Paragliding extends Sport
{
public function __construct(
public readonly string $glider,
) {
}
}
// usage
class Club
{
/**
* @param Sport[] $sports
*/
public function __construct(
public readonly array $sports,
public readonly Sport $sport,
) {
}
}