Giter Club home page Giter Club logo

php-hydrator's Introduction

php-hydrator

phpunit codecov

Одни и те же данные нужно представить в разном виде. В коде удобно работать с высокоуровневыми моделями. Но для сохранения этих данных в базу данных, как правило, данные требуется перевести в более простой вид, обычно в ассоциативный массив. Для передачи данных между приложениями используют простые DTO сущности.

Компонент позволяет легко конвертировать ваши данные в ассоциативный массив из модели и обратно заполнять вашу модель данными.

Extractor

Задача класса Extractor извлечь из вашей модели данные согласно указанынм правилам.

$extractor = new Extractor;
$normalizer = new \PTS\Hydrator\Normalizer;

$model = new Model([
    'id' => 1,
    'name' => 'Alex'
    'email' => '[email protected]'
]);

$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' => '[email protected]
];

$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

php-hydrator's People

Contributors

alexpts avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

dimatiunov

php-hydrator's Issues

Реализация через Reflection

Накидать реализацию через Reflection и приложить время профилирования в Readme файл, с конкретными цифрами.

Сделать каскадное извлечение данных для вложенных моделей

Добавить в схему трансформации поле ref вида.

'ref' => [
    'model' => User::class,
    'map' => 'dto',
    'collection' => false
]

Extractor должен извлечь вложенную модель и рекурсивно извлечь данных из вложенной модели. Для ref типов не будет работать pipe на верхнем уровне. Буде своя полноценная схема трансформации для вложенной модели

Отделить dataTransformer от гидратора

Гидратор сам по себе простой и низкоуровневый. Вынести DataTransformer в отдельный проект, который будет использовать гидратор как зависимость

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.