alexpts / php-hydrator
Convert model to dto, convert dto to model
Requires
- php: >=8.1
Requires (Dev)
- fzaninotto/faker: dev-master
- phpunit/phpunit: ^9.5
Suggests
- ext-blackfire: *
- blackfire/php-sdk: ^1.30
README
Одни и те же данные нужно представить в разном виде. В коде удобно работать с высокоуровневыми моделями. Но для сохранения этих данных в базу данных, как правило, данные требуется перевести в более простой вид, обычно в ассоциативный массив. Для передачи данных между приложениями используют простые DTO сущности.
Компонент позволяет легко конвертировать ваши данные в ассоциативный массив из модели и обратно заполнять вашу модель данными.
Extractor
Задача класса Extractor извлечь из вашей модели данные согласно указанынм правилам.
$extractor = new Extractor; $normalizer = new \PTS\Hydrator\Normalizer; $model = new Model([ 'id' => 1, 'name' => 'Alex' 'email' => 'some@web.dev' ]); $rules = [ 'id' => [], // prop as dto`s key 'name' => [ 'prop' => 'name', // prop is name field in model ], 'email' => [ 'get' => 'getEmail', // getter $model->getEmail(); ] ]; $rules = $normalizer->normalize($rules); $extractor->extract($model, $rules)
Правила извлечения данных описываются в виде ассоциативного массива, где ключ массива это имя ключа в DTO сущности. Наприимер поле модели name можно замапить в поле с именем login в DTO сущности таким образом.
$rules = [ 'login' => [ 'prop' => 'name', ], ... ]; $extractor->extract($model, $rules);
Извлечение через prop позволяет извлеч из модели поле с любой областью видимости (public/protect/private). Если значение prop не указано явно, то оно равно имени ключа DTO сущности. В следующем примере это будет значение name.
$rules = [ 'name' => [], ... ]; $rules = $normalizer->normalize($rules); $extractor->extract($model, $rules)
Помимо извлечения данных свойств из модели, данные можно получить через вызов метода модели (getter).
$rules = [ 'name' => [ 'get' => 'getName', // getter $model->getName(); ], ]; $extractor->extract($model, $rules);
Геттер имеит более высокий приоритет, чем свойтво prop.
Hydrator
Класс Hydrator позволяет наполнить модель данными.
$hydrator = new Hydrator; $dto = [ 'id' => 1, 'login' => 'Alex' 'email' => 'some@web.dev ]; $rules = [ 'id' => [], // prop as dto`s key 'login' => [ 'prop' => 'name', // dto key login fill property name ], 'email' => [ 'set' => 'setEmail', // setter $model->setEmail(); ] ]; $rules = $normalizer->normalize($rules); $model = $hydrator->hydrate($dto, Model::class, $rules); $model2 = new Model; $hydrator->hydrateModel($dto, $model2, $rules);
Правила гидрации точно такие же как и у extractor сущности.
HydratorService
Класс HydratorService является совмещает в себе Hydrator и Extractor. Также он требует правил в виде сущности Rules, которая сглаживает правил и позволяет описывать их более лаконично
$hydratorService = new HydratorService; $rules = [ 'id' => [], // prop as dto`s key 'login' => [ 'prop' => 'name', // dto key login fill property name ], 'email' => [ 'set' => 'setEmail', // setter $model->setEmail(); ] ]; $rules = $normalizer->normalize($rules); $dto = $hydratorService->extract($model, $rules); $model = $hydratorService->hydrate($dto, Model::class, $rules);
Больше возможностей
Если требуется рекурсивная гидрация/извлечение зависимостей, требуется декларативно объявлять правила трансформации, вызывать pipe функции для фильтрации значения, то стоит воспользоваться надсткойкой над этой билбиотекой - https://github.com/alexpts/php-data-transformer2