0

Dot notation for nested config access

Beginner5 min read·lv-05-003

Concept

Dot notation is the key access syntax in Laravel's configuration system. It allows deep traversal of nested PHP arrays using dots as separators.

How it works: config('database.connections.mysql.host') looks up the database config file, then descends into connectionsmysqlhost key of the resulting array. This is implemented by Illuminate\Support\Arr::get() — a utility that walks arrays with dot notation.

Arr::get() and data_get(): These are the underlying helpers. Arr::get(['a' => ['b' => 1]], 'a.b') returns 1. data_get() also works on objects and collections. Both accept a default: Arr::get($array, 'missing.key', 'default').

Config nesting: You can nest as deeply as needed. config('filesystems.disks.s3.key') traverses 4 levels. There's no practical depth limit.

Setting nested values: config(['some.key.nested' => 'value']) creates the nested path if it doesn't exist. Runtime-only — not persisted.

Using dot notation in Eloquent: $order->getTranslation('title', 'en') and some packages use dot notation for JSON columns. Dot notation appears in many places in Laravel beyond config — validation rules, array helpers, JavaScript-like nested data access.

Custom config files: Any PHP file added to config/ is auto-loaded. config/constants.php with return ['version' => '1.0.0'] makes config('constants.version') available.

Code Example

php
<?php
// config/database.php — deeply nested structure
return [
    'default' => env('DB_CONNECTION', 'mysql'),
    'connections' => [
        'sqlite' => [
            'driver' => 'sqlite',
            'database' => env('DB_DATABASE', database_path('database.sqlite')),
        ],
        'mysql' => [
            'driver'    => 'mysql',
            'host'      => env('DB_HOST', '127.0.0.1'),
            'port'      => env('DB_PORT', '3306'),
            'database'  => env('DB_DATABASE', 'laravel'),
            'username'  => env('DB_USERNAME', 'root'),
            'password'  => env('DB_PASSWORD', ''),
            'charset'   => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
        ],
    ],
    'redis' => [
        'default' => [
            'host'     => env('REDIS_HOST', '127.0.0.1'),
            'port'     => env('REDIS_PORT', 6379),
            'database' => env('REDIS_DB', 0),
        ],
    ],
];
php
<?php
// Dot notation access
config('database.default');                          // "mysql"
config('database.connections.mysql.host');           // "127.0.0.1"
config('database.connections.mysql.password');       // ""
config('database.redis.default.port');               // 6379 (integer)

// With default
config('database.connections.pgsql.host', '127.0.0.1'); // default if not set

// Arr helper — same dot notation on any nested array
use Illuminate\Support\Arr;

$data = ['user' => ['profile' => ['theme' => 'dark']]];
Arr::get($data, 'user.profile.theme');           // "dark"
Arr::get($data, 'user.profile.language', 'en'); // "en" (default)
Arr::set($data, 'user.profile.language', 'fr'); // sets nested value
Arr::has($data, 'user.profile.theme');           // true
Arr::forget($data, 'user.profile.theme');        // removes the key

// data_get — works on arrays AND objects AND collections
$user = User::with('profile')->first();
data_get($user, 'profile.theme'); // works on Eloquent model attributes