Arr::add
Sets an array key only when it is missing or null, leaving any existing value untouched.
public static function add($array, $key, $value)- Added in Laravel 5.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$$array | array | The array to add the pair to. It is passed by value and is not modified. |
$$key | string|int|float | The key to write. Dot notation is supported and intermediate arrays are created as needed. |
$$value | mixed | The value to store when the key is considered missing. |
Return value
arrayA new array with the key added when it was missing or null, otherwise a copy of the original array.
Arr::add is a conditional write. Internally it calls Arr::get on the key and only writes when the result is null, which covers two cases: the key is absent, or the key exists and holds null. Every other value — including false, 0 and the empty string — counts as already set and is left alone.
When to reach for it
Use it to layer defaults onto an array you did not build: an options bag from a caller, a request payload you are about to hand to a factory, an attributes array before persisting. It behaves like ??= but understands dot notation, so Arr::add($attributes, 'meta.source', 'web') creates the nested meta array for you rather than failing on a missing parent.
What trips people up
It returns a new array and does not modify the one you pass in. A bare statement such as Arr::add($array, 'price', 100); silently does nothing — you must reassign the result. The second surprise is the null rule: because a stored null is treated as absent, this is not the same test as array_key_exists, and a deliberately nulled value will be replaced.
Example
When to use it
- Filling in default options on a config array supplied by a caller.
- Stamping a default status or source onto an attributes array before creating a model.
- Ensuring a nested key such as meta.locale exists without touching a value the caller already set.
Frequently asked questions
Does Arr::add modify the original array?
No, it returns a new array and leaves the argument untouched, so you must assign the result back. Calling it as a bare statement has no effect.
Why did Arr::add overwrite my null value?
Because null is treated as "not set": the method writes whenever Arr::get on that key returns null. Use Arr::has or array_key_exists if a stored null should block the write.
Can Arr::add create nested keys?
Yes, the key accepts dot notation and any missing intermediate arrays are created for you, so 'meta.source' works on an array that has no meta key yet.
More examples
Dot notation creates the parent
Prints {"name":"Desk","meta":{"source":"web","locale":"en"}}. The first call creates the meta array before writing into it, so you never have to check whether the parent exists. The second call writes into the array the first one created.
<?php
use Illuminate\Support\Arr;
$attributes = ['name' => 'Desk'];
$attributes = Arr::add($attributes, 'meta.source', 'web');
$attributes = Arr::add($attributes, 'meta.locale', 'en');
echo json_encode($attributes), "\n";Applying a defaults table
Prints {"per_page":50,"direction":"asc","sort":"created_at"}. per_page keeps the caller's 50, direction was null so the default replaced it, and sort was missing so it was appended. Note the key order: existing keys keep their original position and added keys go on the end.
<?php
use Illuminate\Support\Arr;
$defaults = [
'per_page' => 15,
'sort' => 'created_at',
'direction' => 'asc',
];
$options = ['per_page' => 50, 'direction' => null];
foreach ($defaults as $key => $value) {
$options = Arr::add($options, $key, $value);
}
echo json_encode($options), "\n";Not a substitute for array_key_exists
Prints {"deleted_at":"never"} then bool(true). The key genuinely exists, but because its value is null Arr::add overwrites it. If a stored null is meaningful in your data, guard with Arr::has or array_key_exists instead of reaching for Arr::add.
<?php
use Illuminate\Support\Arr;
$row = ['deleted_at' => null];
// Arr::add sees null as "not set".
echo json_encode(Arr::add($row, 'deleted_at', 'never')), "\n";
// array_key_exists disagrees.
var_dump(array_key_exists('deleted_at', $row));
Discussion