
Type-safe environment variable validation for Laravel and PHP applications
EnvValidator is a modern, type-safe PHP package for validating environment variables in Laravel and standalone PHP applications. It provides robust validation with clear error messages, intelligent presets, extensible rule objects, and automatic environment file synchronization.
- π Type-safe validation with PHP 8.2+ and PHPStan level max
- π― Smart presets for common scenarios (Laravel, microservices, production, etc.)
- π§© Extensible rule system with custom Rule objects
- π Environment sync to keep
.env
and.env.example
synchronized - π Laravel integration with auto-discovery and Artisan commands
- π¦ Standalone support for non-Laravel PHP applications
- π‘οΈ Production-ready with comprehensive test coverage
- π Clear error messages with detailed validation feedback
composer require dev-kraken/env-validator
You can publish the configuration file with:
php artisan vendor:publish --provider="EnvValidator\EnvValidatorServiceProvider" --tag="config"
use EnvValidator\Facades\EnvValidator;
// Validate with default Laravel rules
EnvValidator::validate();
// Use preset for different scenarios
EnvValidator::useProductionRules()->validate();
EnvValidator::useMinimalRules()->validate();
EnvValidator::useApiRules()->validate();
use EnvValidator\EnvValidator;
// Simple validation with string rules
$rules = [
'APP_ENV' => 'required|string',
'APP_DEBUG' => 'required|boolean',
'APP_URL' => 'required|url',
'DB_HOST' => 'required|string',
'DB_PASSWORD' => 'required|string',
];
$result = EnvValidator::validateStandalone($_ENV, $rules);
if ($result !== true) {
echo "β Environment validation failed:\n";
foreach ($result as $field => $errors) {
foreach ($errors as $error) {
echo " β’ $error\n";
}
}
exit(1);
}
echo "β
Environment validation passed!\n";
use EnvValidator\EnvValidator;
use EnvValidator\Collections\StringRules\{InRule, BooleanRule};
use EnvValidator\Collections\NetworkRules\UrlRule;
$validator = new EnvValidator();
$validator->setRules([
'APP_ENV' => ['required', 'string', new InRule(['staging', 'production'])],
'APP_DEBUG' => ['required', new BooleanRule()],
'APP_URL' => ['required', new UrlRule()],
]);
// For standalone PHP, use validateStandalone method
$result = EnvValidator::validateStandalone($_ENV, $validator->getRules());
if ($result !== true) {
// Handle validation errors
foreach ($result as $field => $errors) {
foreach ($errors as $error) {
echo "Error: $error\n";
}
}
exit(1);
}
echo "β
Environment validation passed!\n";
EnvValidator properly handles required field validation in both Laravel and standalone PHP environments:
// All these formats work for required validation
$rules = [
'APP_KEY' => ['required', 'string', 'min:32'], // Array format (recommended)
'APP_ENV' => 'required|string', // String format
'DB_PASSWORD' => ['required'], // Required only
'API_URL' => ['string', 'required', new UrlRule()], // Required anywhere in array
];
// Standalone validation
$result = EnvValidator::validateStandalone($_ENV, $rules);
if ($result !== true) {
// Handle validation errors
foreach ($result as $field => $errors) {
echo "Error in $field: " . implode(', ', $errors) . "\n";
}
}
Required fields fail validation when they are:
- β Missing from the environment
- β Empty strings (
''
) - β Null values
- β Present with valid values
Preset | Description | Use Case |
---|---|---|
laravel |
Complete Laravel application | Full-featured web applications |
minimal |
Essential variables only | Microservices, lightweight apps |
production |
Production-ready settings | Deployment environments |
api |
API-focused applications | REST APIs, headless applications |
microservice |
Microservice-specific | Containerized services |
docker |
Docker/containerized apps | Container deployments |
// Laravel application
$validator = (new EnvValidator())->usePreset('laravel');
// Microservice
$validator = (new EnvValidator())->usePreset('microservice');
// Production deployment
$validator = (new EnvValidator())->useProductionRules();
// Custom combination
$validator = (new EnvValidator())
->useMinimalRules()
->addRule('CUSTOM_API_KEY', ['required', 'string', 'min:32']);
EnvValidator uses Rule objects for better type safety and maintainability:
use EnvValidator\Collections\StringRules\{InRule, BooleanRule};
use EnvValidator\Collections\NetworkRules\UrlRule;
$rules = [
'APP_ENV' => ['required', 'string', new InRule(['staging', 'production'])],
'APP_DEBUG' => ['required', new BooleanRule()],
'APP_URL' => ['required', new UrlRule()],
];
Benefits:
- π IDE autocompletion and type hints
- π§ͺ Easy unit testing of individual rules
- β»οΈ Reusable across multiple fields
- π¨ Custom error messages with context
- π§ Better debugging and inspection
BooleanRule
- Validates boolean values (true, false, 1, 0, yes, no, etc.)InRule
- Validates value is in a list of allowed valuesKeyRule
- Validates Laravel application keys (base64: format)PatternRule
- Validates against regex patternsEmailRule
- Validates email addressesJsonRule
- Validates JSON strings
NumericRule
- Validates numeric valuesIntegerRule
- Validates integer valuesPortRule
- Validates port numbers (1-65535)
UrlRule
- Validates URLsIpRule
- Validates IP addresses
use EnvValidator\Core\AbstractRule;
class CustomRule extends AbstractRule
{
public function passes($attribute, $value): bool
{
return str_starts_with($value, 'custom_');
}
public function message(): string
{
return 'The :attribute must start with "custom_".';
}
}
// Usage
$validator->addRule('CUSTOM_FIELD', [new CustomRule()]);
// Development environment
if (app()->environment('local', 'development')) {
$validator->useMinimalRules();
} else {
// Production environment
$validator->useProductionRules();
}
$rules = [
'DB_HOST' => ['required_unless:DB_CONNECTION,sqlite', 'string'],
'DB_PORT' => ['required_unless:DB_CONNECTION,sqlite', new PortRule()],
'REDIS_HOST' => ['required_if:CACHE_DRIVER,redis', 'string'],
];
# Validate all environment variables
php artisan env:validate
# Validate specific variables
php artisan env:validate --keys=APP_KEY --keys=APP_URL
# Verbose output with debugging info
php artisan env:validate -v
Keep your .env
and .env.example
files synchronized automatically! This feature helps prevent deployment issues when developers add new environment variables but forget to update the example file.
# Check if .env and .env.example are synchronized
php artisan env:sync --check
Sample Output:
π Checking environment file synchronization...
β οΈ 3 key(s) missing in .env.example, 1 extra key(s) in .env.example
π Statistics:
β’ .env keys: 15
β’ .env.example keys: 13
π Missing in .env.example:
π Sensitive:
β’ STRIPE_SECRET = ********
π Third party:
β’ STRIPE_PUBLIC_KEY = pk_test_1234...
π Application:
β’ FEATURE_FLAG_NEW_UI = true
ποΈ Extra in .env.example:
β’ LEGACY_API_KEY
π‘ Suggestions:
β’ Add missing keys to .env.example
β’ Remove unused keys from .env.example
# Automatically synchronize files (with confirmation)
php artisan env:sync
# Force sync without confirmation
php artisan env:sync --force
# Add keys with empty values (security-conscious)
php artisan env:sync --no-values
# Remove extra keys from .env.example
php artisan env:sync --remove-extra
# Use custom file paths
php artisan env:sync --env-path=/custom/.env --example-path=/custom/.env.example
The sync command automatically handles sensitive data:
- Sensitive keys (PASSWORD, SECRET, KEY, TOKEN) get empty values
- URLs become
https://example.com
- Email addresses become
user@example.com
- Boolean values are standardized to
true
- Numeric values (ports, timeouts) are preserved
- Environment names get appropriate defaults (
production
)
Add environment sync checks to your deployment pipeline:
# In your CI/CD pipeline
php artisan env:sync --check
if [ $? -ne 0 ]; then
echo "β Environment files are out of sync!"
echo "Run 'php artisan env:sync' to fix."
exit 1
fi
use EnvValidator\Services\EnvExampleSyncService;
use EnvValidator\Facades\EnvSync;
// Using the facade
$report = EnvSync::getSyncReport();
if ($report['status'] !== 'synced') {
// Handle out-of-sync files
$result = EnvSync::syncToExample(['generate_values' => true]);
}
// Using the service directly
$syncService = new EnvExampleSyncService();
$report = $syncService->getSyncReport();
// Check specific conditions
if ($syncService->envFileExists() && !$syncService->exampleFileExists()) {
// Create .env.example from .env
$syncService->syncToExample(['generate_values' => true]);
}
// Get validation rule suggestions for new keys
$comparison = $syncService->compareFiles();
$suggestedRules = $syncService->suggestValidationRules(
$comparison['missing_in_example']
);
The environment sync feature works perfectly in standalone PHP applications (without Laravel):
use EnvValidator\Services\EnvExampleSyncService;
// IMPORTANT: Always provide explicit paths in standalone PHP
$syncService = new EnvExampleSyncService(
__DIR__ . '/.env', // Path to your .env file
__DIR__ . '/.env.example' // Path to your .env.example file
);
// Check synchronization status
$report = $syncService->getSyncReport();
if ($report['status'] !== 'synced') {
echo "β οΈ Environment files are out of sync!\n";
// Show what's missing
foreach ($report['missing_in_example'] as $category => $keys) {
echo "Missing {$category} keys: " . implode(', ', array_keys($keys)) . "\n";
}
// Auto-sync files
$result = $syncService->syncToExample([
'add_missing' => true,
'remove_extra' => true,
'generate_values' => true
]);
if ($result['success']) {
echo "β
Files synchronized successfully!\n";
}
}
// Integration with validation
$rules = [
'APP_ENV' => 'required|string',
'DB_HOST' => 'required|string',
'API_KEY' => 'required|string|min:10',
];
$validationResult = EnvValidator::validateStandalone($_ENV, $rules);
if ($validationResult !== true) {
// Handle validation errors
foreach ($validationResult as $field => $errors) {
echo "Error in {$field}: " . implode(', ', $errors) . "\n";
}
}
// Current directory
$syncService = new EnvExampleSyncService(
getcwd() . '/.env',
getcwd() . '/.env.example'
);
// Config directory
$syncService = new EnvExampleSyncService(
getcwd() . '/config/.env',
getcwd() . '/config/.env.example'
);
// Absolute paths
$syncService = new EnvExampleSyncService(
'/var/www/app/.env',
'/var/www/app/.env.example'
);
// Custom file names
$syncService = new EnvExampleSyncService(
getcwd() . '/environment.conf',
getcwd() . '/environment.example.conf'
);
#!/usr/bin/env php
<?php
// deployment.php
require_once 'vendor/autoload.php';
use EnvValidator\Services\EnvExampleSyncService;
use EnvValidator\EnvValidator;
echo "π Deployment: Environment Check\n";
// 1. Check environment sync
$syncService = new EnvExampleSyncService(__DIR__ . '/.env', __DIR__ . '/.env.example');
$report = $syncService->getSyncReport();
if ($report['status'] !== 'synced') {
echo "β ERROR: Environment files are out of sync!\n";
echo "Missing keys: " . count($report['missing_in_example'] ?? []) . "\n";
echo "Extra keys: " . count($report['extra_in_example'] ?? []) . "\n";
exit(1);
}
// 2. Validate environment
$rules = [
'APP_ENV' => 'required|string',
'DB_HOST' => 'required|string',
'API_KEY' => 'required|string|min:32',
];
$result = EnvValidator::validateStandalone($_ENV, $rules);
if ($result !== true) {
echo "β ERROR: Environment validation failed!\n";
foreach ($result as $field => $errors) {
echo " β’ {$field}: " . implode(', ', $errors) . "\n";
}
exit(1);
}
echo "β
Environment check passed - ready for deployment!\n";
- Before Deployments: Always run
php artisan env:sync --check
- In Development: Use
php artisan env:sync
when adding new variables - Team Workflow:
- Add new variables to
.env
- Run
php artisan env:sync
- Commit both
.env.example
and updated validation rules
- Add new variables to
- CI/CD Integration: Fail builds if files are out of sync
- Security: Use
--no-values
flag for highly sensitive projects
- Always specify absolute paths: Use
__DIR__
orgetcwd()
for reliable paths - Check file existence: Use
$syncService->envFileExists()
before operations - Handle errors gracefully: Always check
$result['success']
before proceeding - Integrate with deployment: Add sync checks to your deployment scripts
- Combine with validation: Use sync + validation for complete environment safety
// config/env-validator.php
return [
'validate_on_boot' => ['APP_KEY', 'APP_ENV'], // Validate on app boot
'rules' => [
'CUSTOM_VAR' => ['required', 'string'],
],
'messages' => [
'APP_KEY.required' => 'Application key is required for security.',
],
];
use EnvValidator\Facades\EnvValidator;
// Method chaining
EnvValidator::useProductionRules()
->addRule('API_KEY', ['required', 'string', 'min:32'])
->validate();
// Validate specific keys only
EnvValidator::validateOnly(['APP_KEY', 'APP_ENV']);
# Run all tests
composer test
# Run with coverage
composer test -- --coverage
# Run specific test suite
vendor/bin/pest tests/Unit
vendor/bin/pest tests/Feature
# Static analysis
composer analyse
# Code style check
composer cs
# Fix code style
composer cs:fix
# Run all checks
composer check
The examples/
directory contains comprehensive examples demonstrating various use cases:
comprehensive_examples.php
- Complete feature showcase with presets and rule objectsrequired_field_examples.php
- Detailed required field validation examplesenv_sync_examples.php
- Environment file synchronization demonstrations (Laravel)standalone_env_sync_examples.php
- Environment sync for standalone PHP applicationspreset_examples.php
- Preset system demonstrationsrule_objects_demo.php
- Rule object usage and benefits
// E-commerce application
$validator = (new EnvValidator())
->usePreset('laravel')
->addRules([
'STRIPE_KEY' => ['required', 'string', 'min:32'],
'STRIPE_SECRET' => ['required', 'string', 'min:32'],
'PAYMENT_WEBHOOK_SECRET' => ['required', 'string'],
]);
// Microservice with health checks
$validator = (new EnvValidator())
->usePreset('microservice')
->addRules([
'HEALTH_CHECK_ENDPOINT' => ['required', new UrlRule()],
'SERVICE_TIMEOUT' => ['required', 'integer', 'min:1', 'max:300'],
]);
// Multi-environment configuration
$rules = match(env('APP_ENV')) {
'production' => DefaultRulePresets::production(),
'staging' => DefaultRulePresets::production(),
'testing' => DefaultRulePresets::minimal(),
default => DefaultRulePresets::laravel(),
};
# Run comprehensive examples
php examples/comprehensive_examples.php
# Explore required field validation
php examples/required_field_examples.php
# Environment file synchronization demos (Laravel)
php examples/env_sync_examples.php
# Standalone PHP environment sync demos
php examples/standalone_env_sync_examples.php
# See preset system in action
php examples/preset_examples.php
We welcome contributions! Please see CONTRIBUTING.md for details.
git clone https://github.com/dev-kraken/env-validator.git
cd env-validator
composer install
composer test
The MIT License (MIT). Please see License File for more information.
If you discover any security vulnerabilities, please send an email to soman@devkraken.com instead of using the issue tracker.
- π§ Email: soman@devkraken.com
- π Issues: GitHub Issues
- π¬ Discussions: GitHub Discussions
Made with β€οΈ by Dev Kraken