


FromArray
Data Loader Trait
Introduction
FromArray
is a lightweight PHP trait that enables effortless object hydration from associative arrays. It is
especially useful in scenarios where data needs to be mapped into strongly-typed objects, such as when working with
APIs, form inputs, or configuration data., (*1)
With support for PHP attributes, FromArray
lets you fine-tune how each property is loaded, define type expectations,
and apply custom transformation logic—all while keeping your code clean and expressive., (*2)
Install
composer require om/from-array
Usage
The fromArray
trait enables the creation of object instances preloaded with an initial data array:, (*3)
class Example {
use FromArray;
public string $a;
public string $b;
public string $c;
}
$example = Example::fromArray(
[
'a' => 'value of A',
'b' => 'value of B',
'c' => 'value of C',
],
);
echo json_encode($example, JSON_PRETTY_PRINT);
And that will be the result:, (*4)
{
"a": "value of A",
"b": "value of B",
"c": "value of C"
}
The trait works with public properties only – private and protected properties will be ignored., (*5)
The Property
, Loader
and Type
attributes
There are few PHP Attributes to
configure the fromArray
behavior:, (*6)
Property
The Property
attribute allows you to define a specific key (from
) from the data array that will be mapped to the
property., (*7)
class Example
{
use FromArray;
#[Property(from: '_id')]
public int $id;
}
$example = Example::fromArray(['_id' => 123]);
assert($example->id === 123);
You can also customize the loader
used to load the data:, (*8)
function addPrefix(mixed $value) {
return 'PREFIX_' . $value;
}
class Example
{
use FromArray;
#[Property(loader: 'addPrefix')]
public string $name;
}
$example = Example::fromArray(['name' => 'name']);
assert($example->name === 'PREFIX_name');
Loader can also be the name of a class, an object, or any type of callable function., (*9)
For more see basic-example.php., (*10)
Loader
The Loader
attribute allows you to define a specific value loader for the property. You can add global loaders to the
class or to the property., (*11)
<?php
use DataLoader\Loader;use DataLoader\Property;
class MyLoader {
public function __invoke($value, Property $property){
return match ($property->name) {
'id' => (int) $value,
'names' => explode(',', $value),
default => $value,
}
}
}
#[Loader(MyLoader::class)]
class Example
{
use FromArray;
public mixed $id = null;
public array $names = [];
public string $other = '';
}
$example = Example::fromArray([
'id' => '123',
'names' => 'John,Doe,Smith'
'other' => 'value',
]);
For more see loader-class.php or loader-property.php-, (*12)
Type
The Type
attribute allows you to define a specific type for the property. Types are usually auto detected, but you can
force the type using the Type
attribute., (*13)
class Example
{
use FromArray;
#[Type(name: Types::Int, allowNull: true, class: null)]
public mixed $id;
}
There is one special case for the Type
, you can specify Types::ArrayOfObjects
type to load an array of objects with
the same class. The class
parameter is required in this case., (*14)
class ExampleObject {
public function __construct(public string $name = null) {}
}
class Example
{
use FromArray;
#[Type(name: Types::ArrayOfObjects, class: ExampleObject::class)]
public array $objects = [];
}
$example = Example::fromArray([
'objects' => [
['name' => 'John'],
['name' => 'Doe'],
],
]);
See array-of-objects.php for more information., (*15)
There is a Metadata
object, that contains all the
information about the class and its properties. Metadata
object is singleton, but you can load instance from any type
of cache., (*16)
// prepare metadata
$metadata = new Metadata();
$metadata->resolve(Example::class, MyObject::class);
$data = $metadata->getArrayCopy();
// restore singleton data
Metadata::fromCache($data);
See metadata-cache.php for more information., (*17)
Testing
How to run the tests:, (*18)
composer test # PHP tests
composr format # PHP CS Fixer