With the release of Laravel 8.28 this week, Taylor Otwell contributed two new custom cast types:
AsCollection. ArrayObject has some advantages over the existing casts for JSON and array data.
The pull request description has excellent details to get you up to speed with what these casts bring to Laravel 8:
Of course, Laravel already includes an ability to cast a JSON / TEXT column that contains JSON to an array or collection like so:
$casts = ['options' => 'array'];
However, this does have some downsides. First, the following code is impossible using the simple array cast:
$user = User::find(1); $user->options['foo'] = 'bar'; $user->save();
Many developers probably expect this to work, but it doesn't. It is impossible to mutate a specific property of the primitive array returned by this cast. You must mutate the entire array:
$user = User::find(1); $user->options = ['foo' => 'bar']; $user->save();
However, these new casts utilize Eloquent's custom cast feature, which implements more intelligent management and caching of objects. The
AsArrayObjectcast will cast the underlying JSON string to a PHP
ArrayObjectinstance. This class is included in the standard library of PHP and allows an object to behave like an array. Such an approach makes the following possible:
// Within model... $casts = ['options' => AsArrayObject::class]; // Manipulating the options... $user = User::find(1); $user->options['foo']['bar'] = 'baz'; $user->save(); // You can't use ArrayObject in functions like array_map // You can cast to an array or collection from ArrayObject $user->options->toArray(); $user->options->collect();
I'd recommend checking out Pull Request #36245 for details on the implementation. Read the PR description—it does an excellent job explaining the current state of Laravel casts for array data and the benefits of the new ArrayObject and Collection casts. The PHP documentation is an excellent resource to learn more about the built-in ArrayObject class (introduced in PHP 5), which allows objects to work as arrays.