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 based on usage.
First Use Case:
Replace raw getenv() calls with typed helpers in a non-Laravel context (e.g., Artisan command, queue job, or CLI script):
use PHPStandardLibrary\Env\Env;
$debugMode = Env::bool('APP_DEBUG', false);
$timeout = Env::int('CONNECTION_TIMEOUT', 30);
Laravel Integration (Optional):
For Laravel projects, use alongside existing env() helpers or create a facade:
// app/Helpers/EnvHelper.php
use PHPStandardLibrary\Env\Env;
if (!function_exists('env')) {
function env($key, $default = null) {
return Env::string($key, $default);
}
}
Configuration:
No additional config is required. The package reads from $_ENV or $_SERVER by default, just like getenv().
Replace ad-hoc type casting with explicit helpers:
// Before (error-prone)
$isEnabled = (bool) getenv('FEATURE_X');
// After (type-safe)
$isEnabled = Env::bool('FEATURE_X', false);
Provide sensible defaults for missing or empty variables:
$apiKey = Env::string('API_KEY', 'default-key-123');
$port = Env::int('PORT', 8080);
Combine with custom validation logic:
$maxRetries = Env::int('MAX_RETRIES');
if ($maxRetries < 1 || $maxRetries > 10) {
throw new \RuntimeException('MAX_RETRIES must be between 1 and 10');
}
Create a facade to unify env() calls:
// 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 'env'; }
public static function bool($key, $default = false) {
return Env::bool($key, $default);
}
// Add other typed methods as needed...
}
Use in feature flags or environment-specific configs:
if (Env::bool('FEATURE_NEW_ALGORITHM', false)) {
return new NewAlgorithm();
}
return new LegacyAlgorithm();
config()Use the package for runtime environment variables (e.g., API keys) and Laravel’s config() for static configs:
// config/app.php
'debug' => (bool) env('APP_DEBUG', false),
// In code
$debug = Env::bool('APP_DEBUG'); // Direct access
$debugFromConfig = config('app.debug'); // Cached
vlucas/phpdotenvLoad .env files manually if not using Laravel:
$dotenv = new \Vlucas\Dotenv\Dotenv(__DIR__.'/../');
$dotenv->load();
$dbHost = Env::string('DB_HOST');
Mock environment variables in tests:
// Before test
putenv('TEST_MODE=true');
// Or use a testing helper
Env::override(['TEST_MODE' => true]);
$testMode = Env::bool('TEST_MODE'); // Returns true
Ideal for scripts where Laravel’s helpers aren’t available:
// script.php
$configPath = Env::string('CONFIG_PATH', './config');
require $configPath.'/settings.php';
Env::bool() may not reject all non-boolean strings (e.g., "yes" vs. "true").
Env::bool('FEATURE_X', 'yes'); // Returns `true` (may not be intended)
$value = Env::string('FEATURE_X');
if (!in_array(strtolower($value), ['true', 'false'])) {
throw new \InvalidArgumentException("FEATURE_X must be 'true' or 'false'");
}
$isEnabled = $value === 'true';
$debug = Env::bool(strtoupper('app_debug'), false);
env() and this package, cached configs may not reflect runtime changes..env:
php artisan config:clear
Env::* calls in tight loops (e.g., cron jobs) may impact performance.static $cache = [];
$timeout = $cache['timeout'] ?? $cache['timeout'] = Env::int('CONNECTION_TIMEOUT');
null values in production.// Bad: May return null
$port = Env::int('PORT');
// Good: Explicit default
$port = Env::int('PORT', 80);
Dump all environment variables for debugging:
print_r(getenv());
// Or filter for specific keys
print_r(array_filter($_ENV, fn($k) => str_starts_with($k, 'APP_'), ARRAY_FILTER_USE_KEY));
.env FilesUse a linter to catch missing or invalid variables:
composer require --dev php-parallel-lint/php-parallel-lint
./vendor/bin/parallel-lint .env
For local development, override variables without editing .env:
export APP_DEBUG=true
php artisan serve
Extend the package to support custom types (e.g., Env::json()):
use PHPStandardLibrary\Env\Env;
class EnvExtension {
public static function json($key, $default = null) {
$value = Env::string($key, $default);
return json_decode($value, true) ?: $default;
}
}
Load variables from HashiCorp Vault or AWS SSM:
$vaultClient = new \Hashicorp\Vault\Client();
$secret = $vaultClient->read('secret/data/app');
putenv('DB_PASSWORD=' . $secret['data']['data']['password']);
$password = Env::string('DB_PASSWORD');
Create adapters for other frameworks (e.g., Symfony):
// Symfony EnvironmentAdapter.php
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use PHPStandardLibrary\Env\Env;
class SymfonyEnvAdapter {
public function __construct(private ParameterBagInterface $params) {}
public function get($key, $default = null) {
return $this->params->get($key, Env::string($key, $default));
}
}
Switch between environments at runtime (e.g., for testing):
Env::override(['ENVIRONMENT' => 'testing']);
$env = Env::string('ENVIRONMENT'); // Returns 'testing'
$_ENV may use backslashes (C:\path) on Windows.$path = str_replace('\\', '/', Env::string('APP_PATH'));
$config = base64
How can I help you explore Laravel packages today?