dobrosite / php-mapping
Отображение данных на структуры PHP
Installs: 2 616
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
Requires
- php: ^8.1
- ext-intl: *
Requires (Dev)
- ext-iconv: *
- composer/package-versions-deprecated: ^1.11
- ergebnis/composer-normalize: ^2.28
- fakerphp/faker: ^1.20
- icanhazstring/composer-unused: ^0.8.2
- infection/infection: ^0.26.0,<0.26.6
- phpstan/extension-installer: ^1.1
- phpstan/phpstan: ^1.0
- phpstan/phpstan-phpunit: ^1.0
- phpunit/phpunit: ^9.5,<9.5.17
- rector/rector: ^0.13.10
- roave/security-advisories: dev-latest
- squizlabs/php_codesniffer: ^3.7
- symplify/easy-coding-standard: ^11.1
README
Библиотека компонентов для отображения структурированных данных на структуры PHP и обратно.
Основная идея библиотеки — предоставить «кирпичики» из которых можно построить свои правила отображения данных для любой ситуации.
Определения
- Входные данные (input) — структурированные данные, которые требуется отобразить на структуры PHP.
- Выходные данные (output) — структурированные данные, получаемые из структур PHP.
- Массив (array) — этим словом в библиотеке обозначаются только ассоциативные массивы.
- Коллекция (collection) — индексированный (неассоциативный) массив однотипных значений.
Основы
Сердцем библиотеки являются интерфейсы *Mapper
:
Mapper
Пустой интерфейс, который реализуют все преобразователи.
InputMapper
Преобразователь входных данных. Содержит единственный метод:
public function input(mixed $source): mixed;
OutputMapper
Преобразователь выходных данных. Содержит единственный метод:
Отображает входные данные $source
на структуру PHP и возвращает её.
public function output(mixed $source): mixed;
BidirectionalMapper
Объединяет в себе InputMapper
и OutputMapper
.
Примеры
TODO
BidirectionalMapper
Apply
Применяет ко входным данным преобразователь, полученный от другого преобразователя.
use DobroSite\Mapping; $mapper = new Mapping\Apply( input: new Mapping\Callback( input: fn(mixed $source) => is_numeric($source) ? new Mapping\FloatType() : new Mapping\AsIs(), output: fn(mixed $source) => is_float($source) ? new Mapping\FloatType() : new Mapping\AsIs(), ) ); $mapper->input('123.45'); // 123.45 $mapper->input('foo'); // 'foo'
ArrayKeys
Применяет указанное преобразование последовательно к каждому ключу ассоциативного массива.
use DobroSite\Mapping; $mapper = new Mapping\ArrayKeys( new Mapping\Callback( input: strtolower(...), output: strtoupper(...), ), ); $mapper->input(['FOO' => 'foo value', 'BAR' => 'bar value']); // ['foo' => 'foo value', 'bar' => 'bar value'] $mapper->output(['foo' => 'foo value', 'bar' => 'bar value']); // ['FOO' => 'foo value', 'BAR' => 'bar value']
ArrayKeysMap
Меняет имена ключей массива на основе карты соответствия.
use DobroSite\Mapping; $mapper = new Mapping\ArrayKeysMap([ 'FOO' => 'foo', 'BAR' => 'bar', ]); $mapper->input(['FOO' => 'foo value', 'BAR' => 'bar value']); // ['foo' => 'foo value', 'bar' => 'bar value'] $mapper->output(['foo' => 'foo value', 'bar' => 'bar value']); // ['FOO' => 'foo value', 'BAR' => 'bar value']
ArrayValues
Применяет преобразования к указанным значениям ассоциативного массива.
use DobroSite\Mapping; $mapper = new Mapping\ArrayValues([ 'active' => new Mapping\BooleanType('yes', 'no'), ]); $mapper->input(['active' => 'yes']); // ['active' => true] $mapper->output(['active' => true]); // ['active' => 'yes']
AsIs
Оставляет значения как они есть.
use DobroSite\Mapping; $mapper = new Mapping\AsIs(); $mapper->input('foo'); // 'foo' $mapper->output('foo'); // 'foo'
BooleanType
Преобразовывает значение в булев тип.
use DobroSite\Mapping; $mapper = new Mapping\BooleanType(); $mapper->input('true'); // true $mapper->output(true); // 'true' $mapper = new Mapping\BooleanType(true: 'да', false: 'нет'); $mapper->input('Нет'); // false $mapper->output(false); // 'нет'
Callback
Позволяет использовать для преобразования функции обратного вызова.
use DobroSite\Mapping; $mapper = new Mapping\Callback( input: strtolower(...), output: strtoupper(...), ); $mapper->input('FOO'); // 'foo' $mapper->output('foo'); // 'FOO'
Chained
Создаёт цепочку преобразований, выполняемых последовательно: в input
от первого к последнему,
в output
— в обратном порядке.
use DobroSite\Mapping; $mapper = new Mapping\Chained( $mapper1, $mapper2, // … );
Collection
Применяет указанный преобразователь к каждому элементу коллекции.
use DobroSite\Mapping; $mapper = new Mapping\Collection( new Mapping\FloatType(), ); $mapper->input(['123.45', '67.89']); // [123.45, 67.89]
Constant
Возвращает константное значение.
use DobroSite\Mapping; $mapper = new Mapping\Constant(input: 'foo', output: 'bar'); $mapper->input(uniqid()); // 'foo' $mapper->output(uniqid()); // 'bar'
Constructor
Отображает массив на объект, используя для создания объекта конструктор его класса.
Подробнее см. «Работа с объектами» ниже.
В качестве аргумента $class
в конструктор Constructor
следует передать имя класса или экземпляр
Mapper
, который вернёт имя класса создаваемого объекта.
use App\Foo; use DobroSite\Mapping; $mapper = new Mapping\Constructor(Foo::class); $instanceOfFoo = $mapper->input(['foo' => 'foo value']);
use App\Foo; use App\Bar; use DobroSite\Mapping; $mapper = new Mapping\ObjectConstructor( Mapping\Callback( fn(array $properties) => array_key_exists('bar', $properties) ? Bar::class : Foo::class, ) ); $instanceOfFoo = $mapper->input(['foo' => 'foo value']); $instanceOfBar = $mapper->input(['bar' => 'bar value']);
EnumType
Преобразовывает значения перечисляемых типов.
use App\SomeEnum; use DobroSite\Mapping; $mapper = new Mapping\EnumType(SomeEnum::class); $mapper->input('foo'); // SomeEnum::Foo $mapper->output(SomeEnum::Foo); // 'foo'
FloatType
Преобразовывает значение в вещественное число.
use DobroSite\Mapping; $mapper = new Mapping\FloatType(); $mapper->input('1234.56'); // 1_234.56 $mapper = new Mapping\FloatType( new \NumberFormatter('ru_RU', \NumberFormatter::DEFAULT_STYLE) ); $mapper->input('1 234,56'); // 1_234.56
Map
Преобразовывает значение на основе карты (ассоциативного массива).
use DobroSite\Mapping; $mapper = new Mapping\Map(['foo' => 'bar']); $mapper->input('foo'); // 'bar' $mapper->output('bar'); // 'foo'
Nullable
Модификатор для других преобразователей, разрешающий им принимать значение null
.
use DobroSite\Mapping; $float = new Mapping\FloatType(); $nullable = new Mapping\Nullable($float); $nullable->input('123'); // 123 $nullable->input(null); // NULL $float->input(null); // → InvalidArgumentException
ObjectFactory
Отображает массив на объект, используя для создания объекта фабрику.
Подробнее см. «Работа с объектами» ниже.
В качестве аргумента $factory
в конструктор ObjectFactory
следует передать фабрику для создания
нужных объектов.
use DobroSite\Mapping; $mapper = new Mapping\ObjectFactory('\App\factory_function'); $mapper = new Mapping\ObjectFactory(factory_function(...)); $mapper = new Mapping\ObjectFactory([Factory::class, 'staticMethod']); $mapper = new Mapping\ObjectFactory([$factory, 'method']); $mapper = new Mapping\ClassType\CallableObjectFactory( fn(string $foo, string $bar) => new SomeClass($foo, $bar) );
ObjectMapper
Комбинирующий преобразователь, объединяющий InputMapper
и OutputMapper
для преобразования
массив ⇆ объект.
В первом аргументе (input
) следует передать экземпляр InputMapper
, создающий объект из массива,
например, Constructor или ObjectFactory.
Во втором аргументе (output
) можно передать экземпляр OutputMapper
, создающий массив из объекта.
Если аргумент не указан, будет использован PublicProperties.
use DobroSite\Mapping; $mapper = new Mapping\ObjectMapper( input: new Mapping\Constructor(Foo::class), );
InputMapper
ArrayDefaults
Позволяет задать значения по умолчанию для ключей, отсутствующих во входном массиве.
use DobroSite\Mapping; $mapper = new Mapping\ArrayDefaults([ 'bar' => 'bar value', ]); $mapper->input(['foo' => 'foo value']); // ['foo' => 'foo value', 'bar' => 'bar value']
OutputMapper
Merge
Принимает в конструкторе несколько экземпляров OutputMapper
. При вызове метода output
поочерёдно
передаёт полученное значение каждому из преобразователей, затем объединяет возвращённые ими
результаты с помощью array_merge
.
use DobroSite\Mapping; $mapper = new Mapping\Merge( new Mapping\Constant(output: ['bar' => 'BAR']), new Mapping\Constant(output: ['baz' => 'BAZ']), ); $mapper->output(['foo' => 'FOO']); // ['foo' => 'FOO', 'bar' => 'BAR', 'baz' => 'BAZ']
PublicProperties
Принимает на входе объект, возвращает на выходе ассоциативный массив его публичных свойств.
Предназначен для использования в ObjectMapper
.
Работа с объектами
TODO