php-standard-library/env
Tiny PHP utility for reading environment variables with sensible defaults and type casting. Helps centralize access to config via env(), supports required keys, fallback values, and safe handling when variables are missing or empty.
Installation:
composer require php-standard-library/env
Add to composer.json under require or require-dev depending on usage.
Basic Usage: Import the package and use its core functions:
use PHPStandardLibrary\Env\Env;
// Get a string value with default
$debug = Env::string('APP_DEBUG', 'false');
// Get a boolean value (auto-converts 'true'/'false' strings)
$debugBool = Env::bool('APP_DEBUG', false);
// Get an integer with fallback
$timeout = Env::int('REQUEST_TIMEOUT', 30);
First Use Case:
Replace a single getenv() call in a non-Laravel context (e.g., a CLI script or queue job):
// Before
$queue = getenv('QUEUE_CONNECTION') ?: 'database';
// After
$queue = Env::string('QUEUE_CONNECTION', 'database');
Configuration:
No additional configuration is required. The package reads from $_ENV or $_SERVER by default, just like getenv().
Laravel Integration (Optional):
Create a facade to bridge with Laravel’s env() helper:
// app/Facades/EnvFacade.php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
use PHPStandardLibrary\Env\Env;
class EnvFacade extends Facade
{
protected static function getFacadeAccessor()
{
return function () {
return Env::class;
};
}
}
Replace raw getenv() with typed helpers to enforce data integrity:
// String with default
$apiKey = Env::string('API_KEY', '');
// Boolean (auto-converts 'true'/'false' strings)
$featureEnabled = Env::bool('FEATURE_X', false);
// Integer with validation
$timeout = Env::int('TIMEOUT', 30, ['min' => 1, 'max' => 60]);
// Float with fallback
$precision = Env::float('PRECISION', 2.0);
Use validation rules to reject invalid inputs:
// IP address validation
$ip = Env::string('SERVER_IP', '127.0.0.1', [
'regex' => '/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/'
]);
// Port number validation
$port = Env::int('SERVER_PORT', 80, [
'min' => 1,
'max' => 65535
]);
Set defaults based on the current environment (e.g., production, staging):
$env = Env::string('APP_ENV', 'production');
$debug = Env::bool('APP_DEBUG', $env !== 'production');
Use in non-web contexts where Laravel’s env() is unavailable:
// app/Console/Commands/DeployCommand.php
public function handle()
{
$branch = Env::string('DEPLOY_BRANCH', 'main');
$this->info("Deploying branch: {$branch}");
}
Ensure consistent configuration across queue workers:
// app/Jobs/ProcessPayment.php
public function handle()
{
$maxRetries = Env::int('PAYMENT_RETRIES', 3);
// ...
}
Mock environment variables in tests:
// tests/Feature/ExampleTest.php
public function test_example()
{
putenv('TEST_VAR=test_value');
$value = Env::string('TEST_VAR');
$this->assertEquals('test_value', $value);
}
Facade Wrapper:
Create a facade to unify Laravel’s env() and the package’s API:
// app/Facades/ConfigFacade.php
use Illuminate\Support\Facades\Facade as LaravelFacade;
class ConfigFacade extends LaravelFacade
{
public static function string($key, $default = null)
{
return Env::string($key, $default) ?: config($key, $default);
}
// Add other typed methods as needed
}
Service Provider Binding: Bind the package to Laravel’s container for dependency injection:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton('env', function () {
return new \PHPStandardLibrary\Env\Env();
});
}
Environment File Loading:
Use vlucas/phpdotenv alongside the package for .env support in non-Laravel contexts:
// bootstrap/app.php (or a custom bootstrap file)
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
// Now use Env::* functions
Standalone Scripts: Load environment variables manually before using the package:
// script.php
putenv('SCRIPT_VAR=value');
$value = Env::string('SCRIPT_VAR');
PSR-15 Middleware: Use in middleware to access environment variables:
// app/Middleware/EnvAwareMiddleware.php
public function __invoke($request, $next)
{
$debug = Env::bool('APP_DEBUG', false);
if ($debug) {
// Enable debug logic
}
return $next($request);
}
Symfony Integration:
Replace Symfony’s ParameterBag with the package for environment variables:
// config/services.php
$container->set('env', function () {
return new \PHPStandardLibrary\Env\Env();
});
Boolean Parsing Quirks:
'true', '1', 'yes', etc., to true. If you need strict 'true'/'false' parsing, use Env::string() and manually validate:
$strictBool = Env::string('STRICT_BOOL', 'false') === 'true';
Case Sensitivity:
APP_DEBUG vs. app_debug).Default Value Overrides:
Validation Strictness:
min, max, regex) are not enforced by default. Always check return values or use try-catch:
try {
$port = Env::int('PORT', 80, ['min' => 1, 'max' => 65535]);
} catch (\InvalidArgumentException $e) {
// Handle invalid input
}
Laravel Caching Conflicts:
config() caching, ensure the package’s values are not cached separately to avoid inconsistencies. Prefer config() for Laravel-specific configurations.Null Handling:
null. Always provide a default or handle null explicitly:
$value = Env::string('MISSING_VAR') ?: 'default';
Performance in Loops:
Env::* functions in tight loops (e.g., processing thousands of items). Cache values if they don’t change:
$timeout = Env::int('REQUEST_TIMEOUT', 30); // Cache this value
foreach ($items as $item) {
// Use $timeout here
}
Check Environment Variables:
Env::all() to inspect all loaded environment variables (useful for debugging):
dd(Env::all());
Validate Inputs:
$rawValue = getenv('RAW_VAR');
$processed = Env::string('RAW_VAR', 'default');
Error Handling:
try {
$port = Env::int('PORT', 80, ['min' => 1, 'max' => 65535]);
} catch (\InvalidArgumentException $e) {
Log::error("Invalid PORT value: " . $e->getMessage());
$port = 80; // Fallback
}
Laravel Logs:
How can I help you explore Laravel packages today?