avris/dotenv
Tiny PHP dotenv loader for reading .env files and injecting variables into the environment, $_ENV, and $_SERVER. Supports common KEY=VALUE syntax, quotes, comments, and safe defaults to keep config out of code and VCS.
Installation Add the package via Composer:
composer require avris/dotenv
Basic Setup
Load .env files in your bootstrap/app.php (or equivalent entry point):
use Avris\Dotenv\Dotenv;
$dotenv = Dotenv::createImmutable(__DIR__.'/../');
$dotenv->load();
First Use Case
Access environment variables via Laravel’s env() helper or directly:
$apiKey = env('API_KEY'); // Standard Laravel way
$apiKey = Dotenv::get('API_KEY'); // Direct package access
Standard .env Handling
Replace or supplement Laravel’s default .env loading:
// In bootstrap/app.php
$dotenv = Dotenv::createImmutable(__DIR__.'/../');
$dotenv->load(); // Loads .env file
Custom File Paths
Load .env files from non-standard locations (e.g., per-environment):
$dotenv = Dotenv::createImmutable(__DIR__.'/../../config/envs');
$dotenv->load('staging.env'); // Loads ./config/envs/staging.env
Validation Enforce required variables and types:
$dotenv = Dotenv::createImmutable(__DIR__.'/../');
$dotenv->validate([
'APP_ENV' => 'required|in:local,staging,production',
'DB_PASSWORD' => 'required|string',
'DEBUG_MODE' => 'boolean',
]);
Runtime Overrides Dynamically update variables (e.g., for feature flags):
$dotenv = Dotenv::createImmutable(__DIR__.'/../');
$dotenv->overwrite(['FEATURE_NEW_DASHBOARD' => 'true']);
Service Provider Integration
Bind the Dotenv instance to Laravel’s container:
// In AppServiceProvider
public function register() {
$this->app->singleton(Dotenv::class, function () {
return Dotenv::createImmutable(base_path());
});
}
Then inject it into classes:
use Avris\Dotenv\Dotenv;
public function __construct(private Dotenv $dotenv) {}
Artisan Commands
Use the package to manage .env files via CLI:
use Avris\Dotenv\Dotenv;
use Illuminate\Console\Command;
class EnvCommand extends Command {
protected $signature = 'env:load {path}';
public function handle() {
$dotenv = new Dotenv();
$dotenv->load($this->argument('path'));
$this->info('Environment loaded!');
}
}
Configuration Caching
Cache parsed .env files alongside Laravel’s config:
$dotenv = Dotenv::createImmutable(base_path());
$cached = $dotenv->loadIfExists(); // Loads if .env exists and is cached
Double Loading
.env twice (e.g., in bootstrap/app.php and a service provider) can overwrite values.Dotenv::createImmutable() to prevent reloading:
$dotenv = Dotenv::createImmutable(base_path());
$dotenv->loadIfExists(); // Only loads if not already loaded
Validation Errors
.env files are missing required keys.safeLoad() or loadIfExists() to avoid crashes:
$dotenv->safeLoad(); // Returns false if file is missing/malformed
Laravel Conflicts
env() and Dotenv::get() can lead to inconsistencies if values are set in both.Dotenv for custom logic).Performance Overhead
$dotenv = Dotenv::createImmutable(base_path());
$dotenv->load(); // Load once at boot
Inspect Loaded Variables Dump all loaded variables for debugging:
$dotenv = Dotenv::createImmutable(base_path());
$dotenv->load();
dd($dotenv->getAll()); // Shows all parsed key-value pairs
Check File Paths
Verify the correct .env file is being loaded:
$dotenv = Dotenv::createImmutable('/custom/path');
$dotenv->load('custom.env');
Validation Errors Get detailed validation feedback:
$dotenv = Dotenv::createImmutable(base_path());
$errors = $dotenv->validate([
'DB_HOST' => 'required|string',
]);
if ($errors) {
dd($errors); // Shows validation failures
}
Custom Parsers
Extend the package to support non-standard .env formats:
$dotenv = new Dotenv();
$dotenv->setParser(function ($content) {
// Custom parsing logic
return parse_custom_env($content);
});
Event Listeners
Trigger actions when .env files are loaded:
$dotenv = new Dotenv();
$dotenv->onLoad(function () {
Log::info('Environment loaded');
});
Integration with Laravel Events
Listen to Laravel’s boot events to load .env dynamically:
use Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables;
// Override Laravel’s default env loading
LoadEnvironmentVariables::macro('custom', function () {
$dotenv = new Dotenv();
$dotenv->load(base_path('.env.custom'));
});
Case Sensitivity
.env case sensitivity (e.g., DB_HOST ≠ db_host).Empty Values
KEY=) are treated as empty strings, not null.Boolean Parsing
true/false, 1/0, yes/no).Array Support
ALLOWED_IPS=192.168.1.1\n10.0.0.1).Use .env.example
Document required variables in .env.example:
# .env.example
APP_ENV=local
DB_DATABASE=homestead
Avoid Hardcoding Fallbacks
Dotenv::safeLoad() over Laravel’s env() fallbacks to fail fast.Environment-Specific Files Use naming conventions for clarity:
.env # Default
.env.local # Local overrides
.env.staging # Staging-specific
CI/CD Integration
Validate .env files in pipelines:
# GitLab CI example
test:
script:
- composer require avris/dotenv
- php -r "require 'vendor/autoload.php'; (new \Avris\Dotenv\Dotenv())->validate(['APP_ENV' => 'required']);"
How can I help you explore Laravel packages today?