Arr::dot
Flattens a nested array into a single level whose keys use dot notation to show depth.
public static function dot($array, $prepend = '', $depth = INF)- Added in Laravel 5.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$$array | iterable | The nested array to flatten. |
$$prependoptional | string= '' | A string placed in front of every generated key, usually a prefix ending in a dot. |
$$depthoptional | int= INF | How many levels to descend before treating a value as a leaf. INF flattens all the way down. |
Return value
arrayA single-level array whose keys are dot-joined paths to each leaf value.
Changelog
- PHP 12.xA $depth argument was added. Earlier versions always flattened every level, so code relying on full flattening is unaffected.
Arr::dot walks a nested array and returns a flat array in which each key is the dot-joined path to a leaf value. It is the mechanism behind dotted config lookups: config('mail.mailers.smtp.host') is really a lookup against a dotted key space of this shape.
When to reach for it
It is at its best when you need to treat a tree as a set of paths. Diffing two nested config or translation arrays becomes a plain array_diff_key once both sides are dotted. Validating that every expected setting is present becomes a key check. Rendering a deeply nested payload as a flat table of path and value becomes a single foreach.
What trips people up
Numeric list indexes become key segments, so ['roles' => ['admin']] produces the key roles.0 — dotting a list does not give you back a list. Empty arrays are treated as leaves and kept as an empty-array value rather than vanishing. And a key that already contains a literal dot is indistinguishable from a nesting level afterwards, so the result will not round-trip cleanly through Arr::undot.
Example
When to use it
- Diffing two config or language files to find keys one of them is missing.
- Rendering a nested API payload as a flat table of key path and value.
- Building the dotted key list a validator or feature-flag store expects.
Frequently asked questions
How do I turn a dotted array back into a nested one?
Use Arr::undot, which is the inverse operation. The round trip is lossless only if none of your original keys contained a literal dot.
Why does Arr::dot produce keys like items.0.sku?
Because numeric list indexes are treated as ordinary key segments, so a list nested inside the array contributes its indexes to the path. Arr::undot rebuilds the list from those numeric segments.
What happens to empty arrays in Arr::dot?
An empty array is treated as a leaf and kept under its dotted key with an empty array as its value, so you can still tell an empty branch apart from a missing one.
More examples
Finding keys one config file is missing
Prints ["auth.throttle"]. Once both trees are dotted they are plain single-level arrays, so array_diff_key answers the question directly. Sorting the result keeps the output identical on every run regardless of the original key order.
<?php
use Illuminate\Support\Arr;
$en = ['auth' => ['failed' => 'These credentials do not match.', 'throttle' => 'Too many attempts.']];
$fr = ['auth' => ['failed' => 'Ces identifiants sont incorrects.']];
$missing = array_keys(array_diff_key(Arr::dot($en), Arr::dot($fr)));
sort($missing);
echo json_encode($missing), "\n";Flattening a payload for logging
Prints one line per leaf: order.id = 42, order.customer.email = '[email protected]', order.lines.0.sku = 'A1', order.lines.0.qty = 2. Every nesting level, including the numeric index of the line item, becomes a segment of the key, which is what makes dotted output greppable in logs.
<?php
use Illuminate\Support\Arr;
$payload = [
'order' => [
'id' => 42,
'customer' => ['email' => '[email protected]'],
'lines' => [['sku' => 'A1', 'qty' => 2]],
],
];
foreach (Arr::dot($payload) as $key => $value) {
echo $key, ' = ', var_export($value, true), "\n";
}Limiting the depth
Prints the fully dotted form {"mail.mailers.smtp.host":"smtp.example.com","mail.mailers.smtp.port":587}, then {"mail.mailers.smtp":{"host":"smtp.example.com","port":587}} with the depth capped at two levels. The depth argument exists only in Laravel 12 and later; on earlier versions the third argument is ignored because the parameter does not exist.
<?php
use Illuminate\Support\Arr;
$config = ['mail' => ['mailers' => ['smtp' => ['host' => 'smtp.example.com', 'port' => 587]]]];
echo json_encode(Arr::dot($config)), "\n";
echo json_encode(Arr::dot($config, '', 2)), "\n";
Discussion