Skip to main content

MarshalMapper

Marshals value objects back to plain values. Mappers::marshal() inspects each bindable's object, looks up the mapper provided by the class's #[Marshal]-attributed static method, and runs it — turning an object into the scalar/array that gets written to the target.

A value object declares its marshal mapper with a #[Marshal] attribute on a static method returning a Mapper:

class ValueObjectMock implements StringValueObject, \Stringable {

function __construct(private readonly string $value) { /* ... */ }

#[Marshal]
static function marshalMapper(): Mapper {
return Mappers::value(fn (ValueObjectMock $mock) => $mock->toScalar());
}

function toScalar(): string { return $this->value; }
}

MarshalMapper resolves that mapper once per class and caches it. null bindables pass through unchanged.

Note: marshal is the reverse of unmarshal — unmarshal builds objects from plain input, marshal turns objects back into plain output. Use the two together when a value object crosses the bind boundary in both directions.

Example: marshalling a value object to its scalar​

$values = [];
Bind::values(new ValueObjectMock('test@email.ch'), null)->toArray($values)
->map(Mappers::marshal())
->exec($this->createMock(MagicContext::class));
var_dump($values);

Output:

array(2) {
[0]=>
string(13) "test@email.ch"
[1]=>
NULL
}

The first bindable is the ValueObjectMock; marshal() runs its marshalMapper() and writes 'test@email.ch' to the output array. The second bindable is null, which passes through untouched. If the object's class has no #[Marshal] method, a BindMismatchException is thrown.