Библиотека компонентов для отображения структурированных данных на структуры PHP и обратно.
Основная идея библиотеки — предоставить «кирпичики» из которых можно построить свои правила отображения данных для любой ситуации.
- Входные данные (input) — структурированные данные, которые требуется отобразить на структуры PHP.
- Выходные данные (output) — структурированные данные, получаемые из структур PHP.
- Массив (array) — этим словом в библиотеке обозначаются только ассоциативные массивы.
- Коллекция (collection) — индексированный (неассоциативный) массив однотипных значений.
Сердцем библиотеки являются интерфейсы *Mapper:
Пустой интерфейс, который реализуют все преобразователи.
Преобразователь входных данных. Содержит единственный метод:
publicfunction input(mixed$source): mixed;Преобразователь выходных данных. Содержит единственный метод:
Отображает входные данные $source на структуру PHP и возвращает её.
publicfunction output(mixed$source): mixed;Объединяет в себе InputMapper и OutputMapper.
TODO
Применяет ко входным данным преобразователь, полученный от другого преобразователя.
useDobroSite\Mapping;
$mapper = newMapping\Apply(
input: newMapping\Callback(
input: fn(mixed$source) => is_numeric($source) ? newMapping\FloatType() : newMapping\AsIs(),
output: fn(mixed$source) => is_float($source) ? newMapping\FloatType() : newMapping\AsIs(),
)
);
$mapper->input('123.45'); // 123.45$mapper->input('foo'); // 'foo'Применяет указанное преобразование последовательно к каждому ключу ассоциативного массива.
useDobroSite\Mapping;
$mapper = newMapping\ArrayKeys(
newMapping\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']Меняет имена ключей массива на основе карты соответствия.
useDobroSite\Mapping;
$mapper = newMapping\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']Применяет преобразования к указанным значениям ассоциативного массива.
useDobroSite\Mapping;
$mapper = newMapping\ArrayValues([
'active' => newMapping\BooleanType('yes', 'no'),
]);
$mapper->input(['active' => 'yes']); // ['active' => true]$mapper->output(['active' => true]); // ['active' => 'yes']Оставляет значения как они есть.
useDobroSite\Mapping;
$mapper = newMapping\AsIs();
$mapper->input('foo'); // 'foo'$mapper->output('foo'); // 'foo'Преобразовывает значение в булев тип.
useDobroSite\Mapping;
$mapper = newMapping\BooleanType();
$mapper->input('true'); // true$mapper->output(true); // 'true'$mapper = newMapping\BooleanType(true: 'да', false: 'нет');
$mapper->input('Нет'); // false$mapper->output(false); // 'нет'Позволяет использовать для преобразования функции обратного вызова.
useDobroSite\Mapping;
$mapper = newMapping\Callback(
input: strtolower(...),
output: strtoupper(...),
);
$mapper->input('FOO'); // 'foo'$mapper->output('foo'); // 'FOO'Создаёт цепочку преобразований, выполняемых последовательно: в input от первого к последнему,
в output — в обратном порядке.
useDobroSite\Mapping;
$mapper = newMapping\Chained(
$mapper1,
$mapper2,
// …
);Применяет указанный преобразователь к каждому элементу коллекции.
useDobroSite\Mapping;
$mapper = newMapping\Collection(
newMapping\FloatType(),
);
$mapper->input(['123.45', '67.89']); // [123.45, 67.89]Возвращает константное значение.
useDobroSite\Mapping;
$mapper = newMapping\Constant(input: 'foo', output: 'bar');
$mapper->input(uniqid()); // 'foo'$mapper->output(uniqid()); // 'bar'Отображает массив на объект, используя для создания объекта конструктор его класса.
Подробнее см. «Работа с объектами» ниже.
В качестве аргумента $class в конструктор Constructor следует передать имя класса или экземпляр
Mapper, который вернёт имя класса создаваемого объекта.
useApp\Foo;
useDobroSite\Mapping;
$mapper = newMapping\Constructor(Foo::class);
$instanceOfFoo = $mapper->input(['foo' => 'foo value']);useApp\Foo;
useApp\Bar;
useDobroSite\Mapping;
$mapper = newMapping\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']);Преобразовывает значения перечисляемых типов.
useApp\SomeEnum;
useDobroSite\Mapping;
$mapper = newMapping\EnumType(SomeEnum::class);
$mapper->input('foo'); // SomeEnum::Foo$mapper->output(SomeEnum::Foo); // 'foo' Преобразовывает значение в вещественное число.
useDobroSite\Mapping;
$mapper = newMapping\FloatType();
$mapper->input('1234.56'); // 1_234.56$mapper = newMapping\FloatType(
new \NumberFormatter('ru_RU', \NumberFormatter::DEFAULT_STYLE)
);
$mapper->input('1 234,56'); // 1_234.56Преобразовывает значение на основе карты (ассоциативного массива).
useDobroSite\Mapping;
$mapper = newMapping\Map(['foo' => 'bar']);
$mapper->input('foo'); // 'bar'$mapper->output('bar'); // 'foo'Модификатор для других преобразователей, разрешающий им принимать значение null.
useDobroSite\Mapping;
$float = newMapping\FloatType();
$nullable = newMapping\Nullable($float);
$nullable->input('123'); // 123$nullable->input(null); // NULL$float->input(null); // → InvalidArgumentExceptionОтображает массив на объект, используя для создания объекта фабрику.
Подробнее см. «Работа с объектами» ниже.
В качестве аргумента $factory в конструктор ObjectFactory следует передать фабрику для создания
нужных объектов.
useDobroSite\Mapping;
$mapper = newMapping\ObjectFactory('\App\factory_function');
$mapper = newMapping\ObjectFactory(factory_function(...));
$mapper = newMapping\ObjectFactory([Factory::class, 'staticMethod']);
$mapper = newMapping\ObjectFactory([$factory, 'method']);
$mapper = newMapping\ClassType\CallableObjectFactory(
fn(string$foo, string$bar) => newSomeClass($foo, $bar)
);Комбинирующий преобразователь, объединяющий InputMapper и OutputMapper для преобразования
массив ⇆ объект.
В первом аргументе (input) следует передать экземпляр InputMapper, создающий объект из массива,
например, Constructor или ObjectFactory.
Во втором аргументе (output) можно передать экземпляр OutputMapper, создающий массив из объекта.
Если аргумент не указан, будет использован PublicProperties.
useDobroSite\Mapping;
$mapper = newMapping\ObjectMapper(
input: newMapping\Constructor(Foo::class),
);Позволяет задать значения по умолчанию для ключей, отсутствующих во входном массиве.
useDobroSite\Mapping;
$mapper = newMapping\ArrayDefaults([
'bar' => 'bar value',
]);
$mapper->input(['foo' => 'foo value']);
// ['foo' => 'foo value', 'bar' => 'bar value']Принимает в конструкторе несколько экземпляров OutputMapper. При вызове метода output поочерёдно
передаёт полученное значение каждому из преобразователей, затем объединяет возвращённые ими
результаты с помощью array_merge.
useDobroSite\Mapping;
$mapper = newMapping\Merge(
newMapping\Constant(output: ['bar' => 'BAR']),
newMapping\Constant(output: ['baz' => 'BAZ']),
);
$mapper->output(['foo' => 'FOO']);
// ['foo' => 'FOO', 'bar' => 'BAR', 'baz' => 'BAZ']Принимает на входе объект, возвращает на выходе ассоциативный массив его публичных свойств.
Предназначен для использования в ObjectMapper.
TODO