Arr::dot

Flattens a nested array into a single level whose keys use dot notation to show depth.

Signature
public static function dot($array, $prepend = '', $depth = INF)
  • Added in Laravel 5.0

Parameters

ParameterTypeDescription
$$arrayiterableThe nested array to flatten.
$$prependoptionalstring= ''A string placed in front of every generated key, usually a prefix ending in a dot.
$$depthoptionalint= INFHow 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

Try it yourself
Loading editor…
Press Run to execute the code.

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.

Example · php
<?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.

Example · php
<?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.

Example · php
<?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

  • Be the first to comment on this lesson.