uxf / hydrator
3.41.0
2024-04-28 09:16 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-04-28 07:58:05 UTC
README
The fastest PHP object hydrator....
Install
$ composer req uxf/hydrator
Config
// 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
],
]);
};
Basic usage
ObjectHydrator
create object from
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);
Exceptions
try {
$badPerson = $this->hydrator->hydrateArray($badData, Person::class);
} catch (HydratorException $e) {
/** @var array<string, array<string>> $errors */
$errors = $e->errors;
}
Options
- You can set
default_options
in bundle configuration or as ObjectHydrator constructor parameter. - Or pass
Options
parameter with unique name tohydrateArray
/hydrateArrays
method. - Use unique option name!!! Same option name with different values can lead to unexpected results...
allow_lax_string: true
Convert all scalars or stringable objects to string.
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
Trim all strings.
class Test
{
public function __construct(public readonly string $helloWorld) {}
}
$a = ['helloWorld' => ' A ']; // helloWorld => 'A'
allow_fallback: true
Use FallbackParameterGenerator as fallback hydrator variant.
class Test
{
public function __construct(public readonly mixed $helloWorld) {}
}
$a = ['helloWorld' => ['every value is possible', 1, new DateTime(), ['hello' => 'kitty']];
HydratorProperty
use UXF\Hydrator\Attribute\HydratorProperty;
class Cart
{
public function __construct(
#[HydratorProperty('@id')]
public readonly int $id,
) {
}
}
{
"@id": 1
}
HydratorMap
Interface
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,
) {
}
}
Abstract class
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,
) {
}
}