Перейти к основному содержимому

Инстанцирование объектов

Без конструктора

Если в классе не определён конструктор, Speca заполняет публичные свойства непосредственно из массива входных данных.

class User extends Data {
public string $name;
public int $age;
}

$data = [
'name' => 'John Doe',
'age' => 30,
];

$user = User::from($data);

С конструктором

Если в классе определён конструктор, то он будет инициализирован свойствами из входного массива с соответствующим (возможно, "смапленым" через ParseFrom) именем одного из его аргументов.

Источники данных

На данный момент поддерживается инстанцирование объектов из двух типов данных: массивы и Data-объекты.

Если на входе поступает Data-объект, он будет преобразован в массив с применением соответствующих правил.

Вложенность данных

Speca поддерживает вложенные данные, позволяя создавать сложные агрегаты, включающие в себя другие объекты.

use Looqey\Speca\Data;

class Percent extends ScalarValue {

}

class ScalarValueParser implements Transformer {
public function transform(mixed $value, Property $property): mixed {
// Реализуем парсинг скалярного ValueObject
// - для этого найдем в свойстве тип, отвечающий требованию
$types = $property->getTypes();
foreach ($types as $type) {
if (is_subclass_of($type, ScalarValue::class)) {
//Нашли тип, расширяющий значение - вернем значение, завернутое в него
return new $type($value);
}
}
// Не смогли найти нужный тип. Можно выбросить исключение,
// а можно вернуть значение, если после этого парсера вы разместите другой,
// который попробует привести значение к другой группе типов (если это потребуется)
throw new \Exception("No ScalarValue childs were declared in $property->name");
}
}

class SpecialDiscount extends Data {
public function __construct(
#[ParseBy(ScalarValueParser::class)]
public Percent $amount,
public array $category_ids
) {}
}

class UserDiscountAggregate extends Data {
public function __construct(
public User $user,
public ?SpecialDiscount $discount = null
) {}
}

Входные данные могут быть как обычными массивами, так и Data-объектами:

$data = [
'user' => [
'name' => 'John Doe',
'age' => 25
],
'discount' => [
'amount' => 10,
'category_ids' => [1, 2, 3]
]
];

$agg = UserDiscountAggregate::from($data);