Библиотека компонентов для отображения структурированных данных на структуры 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