Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Dotenv Laravel Package

symfony/dotenv

Symfony Dotenv reads .env files and exposes variables via $_ENV/$_SERVER. Load one or multiple files, optionally overwrite existing values, or use loadEnv() to handle .env.local and environment-specific variants for local development and deployment.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require symfony/dotenv
    

    Add to composer.json under require:

    "symfony/dotenv": "^8.0"
    
  2. Basic Usage: Create a .env file in your project root:

    APP_NAME=MyLaravelApp
    DB_HOST=localhost
    

    Load it in your Laravel application (e.g., in bootstrap/app.php or a service provider):

    use Symfony\Component\Dotenv\Dotenv;
    
    $dotenv = new Dotenv();
    $dotenv->load(__DIR__.'/../.env');
    
  3. Access Variables:

    $appName = $_ENV['APP_NAME'] ?? $_SERVER['APP_NAME'] ?? null;
    $dbHost = $_ENV['DB_HOST'] ?? $_SERVER['DB_HOST'] ?? 'default';
    
  4. Leverage Laravel’s Built-in Support: Laravel already integrates symfony/dotenv via Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables. No additional code is needed in most cases—just ensure .env exists.


Implementation Patterns

Core Workflows

  1. Environment Loading Hierarchy:

    • Use loadEnv() for automatic loading of .env, .env.local, and .env.{APP_ENV}.local:
      $dotenv->loadEnv(__DIR__.'/../.env');
      
    • Override with overload() for explicit file prioritization:
      $dotenv->overload(__DIR__.'/../.env.production');
      
  2. Variable Expansion: Reference other variables in .env:

    APP_URL=https://${APP_DOMAIN}
    APP_DOMAIN=example.com
    

    Symfony resolves ${APP_DOMAIN} during loading.

  3. Conditional Loading: Load environment files based on runtime conditions (e.g., APP_ENV):

    $envFile = __DIR__.'/../.env.'.($_ENV['APP_ENV'] ?? 'local');
    $dotenv->load($envFile);
    
  4. Integration with Laravel:

    • Service Providers: Load environments in a provider’s boot() method:
      public function boot(): void
      {
          $dotenv = new Dotenv();
          $dotenv->load(__DIR__.'/../../.env');
      }
      
    • Artisan Commands: Load environments dynamically:
      use Symfony\Component\Dotenv\Dotenv;
      
      protected function handle(): void
      {
          $dotenv = new Dotenv();
          $dotenv->load(__DIR__.'/../../.env');
          // Command logic...
      }
      
  5. Testing: Use overload() to inject test-specific environments:

      $dotenv->overload(__DIR__.'/../../.env.testing');
    

Advanced Patterns

  1. Custom Paths: Override the default .env path via SYMFONY_DOTENV_PATH:

    SYMFONY_DOTENV_PATH=/custom/path/to/.env
    
  2. Dynamic File Generation: Generate .env files programmatically (e.g., from a database or API):

    $envContent = "DB_PASSWORD=".password_generate();
    file_put_contents(__DIR__.'/../.env', $envContent);
    $dotenv->load(__DIR__.'/../.env');
    
  3. Validation: Combine with vlucas/phpdotenv or custom validation to enforce variable formats:

    if (!filter_var($_ENV['APP_URL'], FILTER_VALIDATE_URL)) {
        throw new \RuntimeException('Invalid APP_URL in .env');
    }
    
  4. Security:

    • Sensitive Data: Use phpdotenv’s .env.local for secrets (excluded from Git).
    • Runtime Masking: Log sanitized values:
      $dbPassword = $_ENV['DB_PASSWORD'] ?? '';
      \Log::debug("DB_PASSWORD set (masked)");
      

Gotchas and Tips

Pitfalls

  1. Variable Corruption:

    • Issue: Loading .env multiple times corrupts variables (fixed in v8.0.9+).
    • Fix: Use load() once or overload() for updates.
    • Workaround: Clear $_ENV/$_SERVER before reloading:
      $_ENV = [];
      $_SERVER = array_merge($_SERVER, ['APP_ENV' => 'local']);
      
  2. Self-Referencing Variables:

    • Issue: Circular references (e.g., A=${B}, B=${A}) cause infinite loops.
    • Fix: Use overload() to prioritize files or restructure variables.
  3. Escaped Dollars:

    • Issue: $ in values (e.g., DB_PASSWORD=pass$word) may break expansion.
    • Fix: Escape with \\:
      DB_PASSWORD=pass\\$word
      
  4. BOM (Byte Order Mark):

    • Issue: .env files with BOM (common in Windows) throw errors.
    • Fix: Remove BOM or use UTF-8 without BOM in your editor.
  5. Case Sensitivity:

    • Issue: $_ENV is case-insensitive on Linux but case-sensitive on Windows.
    • Fix: Standardize keys (e.g., APP_ENV instead of app_env).
  6. NUL Bytes:

    • Issue: Values with NUL bytes (e.g., from APIs) may corrupt parsing.
    • Fix: Sanitize inputs or use str_replace("\0", '', $value) before writing to .env.

Debugging Tips

  1. Inspect Loaded Variables:

    var_dump($_ENV, $_SERVER);
    

    Or use Symfony’s debug command:

    php bin/console debug:dotenv
    
  2. Check File Permissions: Ensure .env is readable by the web server (e.g., chmod 644 .env).

  3. Validate Syntax: Use an online .env validator or test with:

    $dotenv = new Dotenv();
    try {
        $dotenv->load(__DIR__.'/../.env');
    } catch (\Exception $e) {
        echo "Error: ".$e->getMessage();
    }
    
  4. CI/CD Pitfalls:

    • GitHub Actions: Add .env to .gitignore but use secrets:
      env:
        DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
      
    • Docker: Mount .env files as volumes or use env_file in docker-compose.yml.

Extension Points

  1. Custom Parsers: Extend Symfony\Component\Dotenv\Parser to support custom formats (e.g., YAML):

    use Symfony\Component\Dotenv\Parser\Parser;
    
    class CustomParser extends Parser {
        public function parse(string $content): array {
            // Custom logic...
        }
    }
    
  2. Event Listeners: Hook into Dotenv events (e.g., after loading) via dependency injection:

    $dotenv->addListener('afterLoad', function () {
        // Post-processing logic
    });
    
  3. Laravel-Specific:

    • Override Default Path: Publish and modify config/dotenv.php:
      'path' => base_path('.env.custom'),
      
    • Custom Bootstrapping: Extend LoadEnvironmentVariables:
      namespace App\Foundation\Bootstrap;
      
      use Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables as Original;
      
      class LoadEnvironmentVariables extends Original {
          public function bootstrap(): void {
              parent::bootstrap();
              // Additional logic
          }
      }
      
  4. Performance:

    • Cache Loading: Store parsed variables in a static cache for repeated calls:
      static $cachedEnv = null;
      if (!$cachedEnv) {
          $dotenv = new Dotenv();
          $cachedEnv = $dotenv->load(__DIR__.'/../.env');
      }
      

Configuration Quirks

  1. APP_ENV Priority:

    • Files like .env.production.local are loaded after .env.production, so later files override earlier ones.
  2. Empty Values:

    • KEY= sets the value to an empty string (not null). Use KEY="" for clarity.
  3. Windows Paths:

    • Use forward slashes (/) or double backslashes (\\) in paths:
      LOG_PATH=C:\\logs\\app
      
  4. PHP Constants:

    • Avoid naming variables after PHP constants (e.g., true, false, null) to prevent conflicts.
  5. Heredoc Syntax:

    • Use <<< 'EOF' for multi-line values (avoid <<<EOF to prevent syntax errors):
      MESSAGE<<< 'EOF'
      This is a
      multi-line value.
      EOF
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope