dvelum / dr
Data Record
Requires
- php: ~7.4
Requires (Dev)
- codacy/coverage: dev-master
- phpstan/phpstan: ^0.12
- phpunit/phpunit: ^9
README
Data Record - Инструмент для создания и валидации структур данных
Позволяет создавать и валидировать структуры данных, без привязки к БД / ActiveRecord / ORM.
Можно использовать как замену DTO.
Можно использовать как замену валидатора Active Record или ORM в проектах, где нет желания использовать массивные ORM.
Конечную структуру можно экспортировать в массив, далее сохранить в БД.
Кроме стандартных типов данных и валидаторов, позволяет регистрировать свои.
Преимущества
- не нужно создавать обилие классов под каждый тип, заполнять их полями, геттерами и сеттерами
- экономит время на разработку, количество кода в рантайме
- стандартные проверки полей типа minVal, maxVal, maxLength, defaultValue, isNullable делаются одной настройкой в файле конфигурации
- есть возможность проверить всели ли required поля заполнены
- есть слежение за состоянием изменения (получить список полей которые изменились)
- можно создавать собственные (custom) типы данных (достаточно просто)
- использует ленивую загрузку, экономит оперативную память
- значительно меньшее потребление памяти относительно DTO
- автоматическая конвертация типов, например DateTime
$record->set('dateTimeField', '2021-01-01 00:00:00'); /** * @var \DateTime $result */ $result = $record->get('dateTimeField');
Установка
composer require dvelum/dr
Упрощенный пример использования
Файл настроек реестра Records registry.php
<?php use Dvelum\DR\Type\StringType; use Dvelum\DR\Type\DateTimeType; use Dvelum\DR\Record\DefaultValue\CurrentDateTimeString; $registry = [ 'records'=> [ 'ClientData' => [ 'fields' => [ 'firstName' => [ 'type' => 'string', // можно StringType::class 'minLength' => 2, 'required' => true, ], 'age' => [ 'type' => 'int', 'minValue' => 18, 'default' => 18, ], 'date' => [ 'type' => DateTimeType::class, 'minValue' => '2021-01-01', 'defaultValueAdapter' => CurrentDateTimeString::class ] ] ] ] ];
Использование:
<?php use Dvelum\DR\Factory; // получаем данные POST из запроса $params = $psr7Request->getParsedBody(); // получаем настройки реестра $registry = include 'registry.php'; // создаем фабрику DR $factory = new Factory($registry); //=== Пример 1 ================================ $record = $factory->create('ClientData'); try{ $record->setData($params); }catch(\InvalidArgumentException $e){ // переданы невалидные данные } // можно проверить все ли обязательные поля переданы if(!$record->validateRequired()->isSuccess()){ // не все обязательные поля заданы } //=== Пример 2 ================================ // получаем id записи из параметров запроса $id = $psr7Request->getQueryParams()['id']; /** * Загружаем данные из нашего хранилища * @var array $clientData */ $clientData = $someStorage->load($id); $record = $factory->create('ClientData'); // помещаем данные из хранилища в структуру $record->setData($clientData); // помечаем изменения как принятые $record->commitChanges(); try{ // сетим данные из запроса $record->setData($params); }catch(\InvalidArgumentException $e){ // переданы невалидные данные } // Для удобства экспорта данных в хранилище, например в БД, есть подготовленный класс экспорта, // который конвертирует поля в нужный вид (например json поле в строку, DateTime в строку формата 'Y-m-d H:i:s') $export = new \Dvelum\DR\Export\Database(); // получить все данные $data = $export->exportRecord($record); // или получить только обновления $data = $export->exportUpdates($record); // Export можно получить и из объекта $factory->getExport('ExportAlias'), тогда его нужно будет зарегистрировать при создании $factory // и получить командой: /** * @var ExportInterface $export */ $export = $factory->getExport('Database');
Отсутствие подсветки полей в IDE можно компенсировать UI пакетом dvelum\dr-ui
Экспериментальный пакет, позволяет просматривать ваши структуры данных.
Пока доступен только просмотр, возможно будет добавлено и редактирование.
Запускается одной командой на локальном хосте linux/macos
Производительность
Сравнение DataRecord с DTO, тест на заполнение 50,000 объектов.
PHP 7.4, xdebug отключен, cli opcache включен.
php test/tests/performance/create.php
- создать рандомный датасет
php test/tests/performance/dto.php
- заполнение DTO
php test/tests/performance/record.php
- заполнение Record
php test/tests/performance/record.php -r 1
- заполнение Record при помощи setRawData
Время, c | RAM, mb | |
---|---|---|
DTO | 0.025 | 13.177 |
DR | 0.146 | 2.016 |
DR raw | 0.036 | 2.016 |
Data Record потребляет значительно меньше (6.5 раз) оперативной памяти за счет оптимизаций, но по времени выполнения естественно уступает нативным иструментам (5.5 раз), так как валидаций больше и выполняются они в коде.
Для повышения производительности заполнения Data Record есть метод setRawData, который заполняет Record без валидаций. Этим методом можно воспользоваться когда данные приходят из бд и мы им доверяем (уверенны, что они провалидированы перед записью). В этом случае разница в скорости выполнения минимальна.
Валидации "из коробки" больше, кода писать нужно значительно меньше, вполне конкурентное решение имеющее право на жизнь.