Data Objects
A Data object extends BradieTilley\Data\Data and declares its shape as a typed
constructor.
use BradieTilley\Data\Data;
class ProductData extends Data
{
public function __construct(
public string $title,
public int $reviews,
public float $rating,
) {}
}
Every public promoted property becomes part of the object's serialized shape. The constructor signature is the single source of truth — there is no separate schema to keep in sync.
Computed properties
You can set additional public properties in the constructor body. They are
serialized alongside the promoted ones. Note that a non-promoted constructor
argument (here $ratings) is used only to compute state and is not itself a
property, so it is not serialized.
class CustomPropertiesData extends Data
{
public float $averageRating;
public function __construct(
public string $title,
array $ratings,
) {
$this->averageRating = collect($ratings)->avg();
}
}
CustomPropertiesData::from(['title' => 'Widget', 'ratings' => [4, 5, 3]])->toArray();
// ['title' => 'Widget', 'averageRating' => 4.0]
For properties that should never be hydrated from input, use
#[Computed].
Default values
Constructor defaults are honoured when a value is absent from the input:
class DefaultPropertiesData extends Data
{
public function __construct(
public string $title,
public bool $active = true,
) {}
}
DefaultPropertiesData::from(['title' => 'Widget'])->toArray();
// ['title' => 'Widget', 'active' => true]
Readonly properties
readonly promoted properties are fully supported and behave exactly as native
PHP readonly properties.
class ReadonlyPropertiesData extends Data
{
public function __construct(
public readonly string $title,
) {}
}
Typed features at a glance
| Property type | Behaviour |
|---|---|
Scalars (string, int, float, bool) | Copied as-is |
BackedEnum | Scalar input is hydrated to the enum; serialized back to its scalar value |
Nested Data | Recursively hydrated / serialized — see Nested & Collections |
array / Collection | Optionally typed per-item with #[ArrayOf] |
Carbon / CarbonImmutable | Parsed on input, formatted on output (see #[DateFormat]) |
Continue to Hydration for the ways to build an instance.