Библиотека компонентов для отображения структурированных данных на структуры PHP и обратно.
Основная идея библиотеки — предоставить «кирпичики» из которых можно построить свои правила отображения данных для любой ситуации.
- Входные данные (input) — структурированные данные, которые требуется отобразить на структуры PHP.
- Выходные данные (output) — структурированные данные, получаемые из структур PHP.
- Массив (array) — этим словом в библиотеке обозначаются только ассоциативные массивы.
- Коллекция (collection) — индексированный (неассоциативный) массив однотипных значений.
Сердцем библиотеки являются интерфейсы *Mapper:
Пустой интерфейс, который реализуют все преобразователи.
Преобразователь входных данных. Содержит единственный метод:
public function input(mixed $source): mixed;Преобразователь выходных данных. Содержит единственный метод:
Отображает входные данные $source на структуру PHP и возвращает её.
public function output(mixed $source): mixed;Объединяет в себе InputMapper и OutputMapper.
TODO
Применяет ко входным данным преобразователь, полученный от другого преобразователя.
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'Применяет указанное преобразование последовательно к каждому ключу ассоциативного массива.
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']Меняет имена ключей массива на основе карты соответствия.
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']Применяет преобразования к указанным значениям ассоциативного массива.
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']Оставляет значения как они есть.
use DobroSite\Mapping;
$mapper = new Mapping\AsIs();
$mapper->input('foo'); // 'foo'
$mapper->output('foo'); // 'foo'Преобразовывает значение в булев тип.
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); // 'нет'Позволяет использовать для преобразования функции обратного вызова.
use DobroSite\Mapping;
$mapper = new Mapping\Callback(
input: strtolower(...),
output: strtoupper(...),
);
$mapper->input('FOO'); // 'foo'
$mapper->output('foo'); // 'FOO'Создаёт цепочку преобразований, выполняемых последовательно: в input от первого к последнему,
в output — в обратном порядке.
use DobroSite\Mapping;
$mapper = new Mapping\Chained(
$mapper1,
$mapper2,
// …
);Применяет указанный преобразователь к каждому элементу коллекции.
use DobroSite\Mapping;
$mapper = new Mapping\Collection(
new Mapping\FloatType(),
);
$mapper->input(['123.45', '67.89']); // [123.45, 67.89]Возвращает константное значение.
use DobroSite\Mapping;
$mapper = new Mapping\Constant(input: 'foo', output: 'bar');
$mapper->input(uniqid()); // 'foo'
$mapper->output(uniqid()); // 'bar'Отображает массив на объект, используя для создания объекта конструктор его класса.
Подробнее см. «Работа с объектами» ниже.
В качестве аргумента $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']);Преобразовывает значения перечисляемых типов.
use App\SomeEnum;
use DobroSite\Mapping;
$mapper = new Mapping\EnumType(SomeEnum::class);
$mapper->input('foo'); // SomeEnum::Foo
$mapper->output(SomeEnum::Foo); // 'foo' Преобразовывает значение в вещественное число.
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Преобразовывает значение на основе карты (ассоциативного массива).
use DobroSite\Mapping;
$mapper = new Mapping\Map(['foo' => 'bar']);
$mapper->input('foo'); // 'bar'
$mapper->output('bar'); // 'foo'Модификатор для других преобразователей, разрешающий им принимать значение 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Отображает массив на объект, используя для создания объекта фабрику.
Подробнее см. «Работа с объектами» ниже.
В качестве аргумента $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)
);Комбинирующий преобразователь, объединяющий InputMapper и OutputMapper для преобразования
массив ⇆ объект.
В первом аргументе (input) следует передать экземпляр InputMapper, создающий объект из массива,
например, Constructor или ObjectFactory.
Во втором аргументе (output) можно передать экземпляр OutputMapper, создающий массив из объекта.
Если аргумент не указан, будет использован PublicProperties.
use DobroSite\Mapping;
$mapper = new Mapping\ObjectMapper(
input: new Mapping\Constructor(Foo::class),
);Позволяет задать значения по умолчанию для ключей, отсутствующих во входном массиве.
use DobroSite\Mapping;
$mapper = new Mapping\ArrayDefaults([
'bar' => 'bar value',
]);
$mapper->input(['foo' => 'foo value']);
// ['foo' => 'foo value', 'bar' => 'bar value']Принимает в конструкторе несколько экземпляров 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']Принимает на входе объект, возвращает на выходе ассоциативный массив его публичных свойств.
Предназначен для использования в ObjectMapper.
TODO