Skip to main content

PropsClosureMapper

A multi-bindable mapper: passes a map of the current bindable values (keyed by relative name) to a closure and writes the returned map back. Bindables whose name appears in the return map are updated; bindables absent from the return map are dropped; new names in the return map are acquired as new bindables.

The closure receives either a plain array (for Mappers::values() / valuesAny() / valuesEvery()) or a BindData wrapping that array (for Mappers::propsAsBindDataClosure()), and must return an array (or BindData).

The three variants differ in when the closure runs:

FactoryMultiMapModeBehavior
Mappers::values()ALWAYSAlways runs, even when no declared bindable is present.
Mappers::valuesAny()ANY_BINDABLE_MUST_BE_PRESENTSkipped unless at least one declared bindable is present.
Mappers::valuesEvery()EVERY_BINDABLE_MUST_BE_PRESENTSkipped unless every declared bindable is present.

Mappers::propsClosure() / propsClosureAny() / propsClosureEvery() are deprecated aliases for the three above.

Example: transforming and renaming props​

$result = Bind::attrs(['password' => 'secret'])
->props(['password'], Mappers::values(fn ($values) => [
'passwordHash' => 'hash:' . $values['password'],
]))
->toArray()
->exec();
var_dump($result->get());

Output:

array(1) {
["passwordHash"]=>
string(11) "hash:secret"
}

password is dropped (it is not in the return map) and passwordHash is acquired as a new bindable.

Example: typed access with BindData​

Mappers::propsAsBindDataClosure() hands the closure a BindData instead of a raw array, so you can use typed accessors.

$result = Bind::attrs(['string' => 'test'])
->props(['string'], Mappers::propsAsBindDataClosure(function (BindData $bindData) {
return [
'string' => $bindData->reqString('string') . '-holeradio',
'int' => 7,
];
}))
->toArray()
->exec();
var_dump($result->get());

Output:

array(2) {
["string"]=>
string(14) "test-holeradio"
["int"]=>
int(7)
}