Understanding Laravel Configuration

+15 Mana ✨

Introduction

Every Laravel application is tuned through a tree of PHP files under config/. This lesson explains how configuration is loaded, how to read values with the config() helper, and how to override values at runtime.

Key Concepts

  • config/ directory: One PHP file per domain (app, database, cache, mail, queue).
  • Dot notation: config('app.name') — the first segment is the filename, the rest are array keys.
  • Config caching: php artisan config:cache compiles every config file into a single cached blob.
  • Runtime override: config(['app.timezone' => 'UTC']) changes a value for the current request only.
  • Maintenance mode: php artisan down puts the app behind a maintenance page.

Real World Context

Every production Laravel app caches its config for performance. This is the reason you cannot call env() outside config files — when the config cache is warm, .env is never read.

Deep Dive

Laravel's configuration system is both powerful and flexible. All configuration files are stored in the config directory, and each option is well-documented.

The config Directory

Laravel includes configuration files for every major feature:

config/
├── app.php         # Application settings (name, timezone, locale)
├── auth.php        # Authentication guards and providers
├── cache.php       # Cache drivers and settings
├── database.php    # Database connections
├── filesystems.php # File storage disks
├── mail.php        # Email settings
├── queue.php       # Queue connections
├── services.php    # Third-party service credentials
└── session.php     # Session driver and settings

Accessing Configuration Values

Use the config() helper to access configuration values:

php
// Get a configuration value
$appName = config('app.name');         // 'Laravel'
$timezone = config('app.timezone');    // 'UTC'

// Nested configuration
$driver = config('database.default');  // 'sqlite'

// With a default value
$value = config('app.custom_key', 'default');
Dot Notation

Configuration uses dot notation where:

  • First segment = filename (without .php)
  • Following segments = array keys
php
// config/app.php
return [
    'name' => env('APP_NAME', 'Laravel'),
    'env' => env('APP_ENV', 'production'),
    'debug' => env('APP_DEBUG', false),
];

// Accessing these values
config('app.name');   // First 'app' = file, 'name' = key
config('app.debug');

Setting Configuration at Runtime

You can set configuration values at runtime:

php
// Set a single value
config(['app.timezone' => 'America/New_York']);

// Set multiple values
config([
    'app.timezone' => 'America/New_York',
    'app.debug' => true,
]);

Note: Runtime configuration changes only last for the current request.

Configuration Structure

Each config file returns a PHP array:

php
// config/app.php
<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Application Name
    |--------------------------------------------------------------------------
    |
    | This value is the name of your application, which will be used when the
    | framework needs to place the application's name in a notification or
    | other UI elements where an application name needs to be displayed.
    |
    */

    'name' => env('APP_NAME', 'Laravel'),

    'env' => env('APP_ENV', 'production'),

    'debug' => (bool) env('APP_DEBUG', false),

    'url' => env('APP_URL', 'http://localhost'),

    'timezone' => env('APP_TIMEZONE', 'UTC'),

    'locale' => env('APP_LOCALE', 'en'),
];

The config/app.php File

The main application configuration includes:

php
return [
    // Application name
    'name' => env('APP_NAME', 'Laravel'),

    // Environment (local, staging, production)
    'env' => env('APP_ENV', 'production'),

    // Debug mode (show detailed errors)
    'debug' => (bool) env('APP_DEBUG', false),

    // Application URL
    'url' => env('APP_URL', 'http://localhost'),

    // Timezone for PHP date functions
    'timezone' => env('APP_TIMEZONE', 'UTC'),

    // Locale for translations
    'locale' => env('APP_LOCALE', 'en'),

    // Fallback locale
    'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'),

    // Application key (for encryption)
    'key' => env('APP_KEY'),
    'cipher' => 'AES-256-CBC',
];

Debug Mode

Debug mode shows detailed error messages with stack traces:

php
// .env
APP_DEBUG=true   // Development: shows full errors
APP_DEBUG=false  // Production: shows generic error page

Warning: Never enable debug mode in production! It exposes sensitive information.

Maintenance Mode

Laravel can put your application in maintenance mode:

bash
# Enable maintenance mode
php artisan down

# With a custom message
php artisan down --message="Upgrading Database"

# Allow certain IPs
php artisan down --allow=127.0.0.1

# Disable maintenance mode
php artisan up

Common Pitfalls

  1. Calling env() from a controller — It returns null in production once config is cached. Always go through config().
  2. Leaving APP_DEBUG=true in production — It leaks stack traces, environment variables, and SQL queries to visitors.

Best Practices

  1. Run php artisan config:cache during deploy — A cached config speeds up every request.
  2. Add your own values to a config file, not .env directly — Define config/services.stripe.key once and read it everywhere via config().

Summary

  • Configuration lives in config/*.php and is accessed through config() with dot notation.
  • .env provides values to config files; it is not read by application code.
  • config:cache compiles everything into a single cached file for production.
  • APP_DEBUG=false is mandatory in production.
  • Use php artisan down/up for maintenance windows.
✓ Completed