ashallendesign/laravel-config-validator
Validate your Laravel config at runtime or via Artisan. Define rulesets for config files with custom messages and environment targeting, generate rulesets quickly, and optionally publish defaults. Catch missing/invalid config early in local, CI, or production.
Installation:
composer require ashallendesign/laravel-config-validator
Publish the default ruleset configuration:
php artisan vendor:publish --provider="AshAllenDesign\ConfigValidator\ConfigValidatorServiceProvider" --tag="config-validator-rulesets"
First Use Case:
Define a validation rule in config/config-validator.php:
'rulesets' => [
'app' => [
'env' => ['required', 'in:local,staging,production'],
'debug' => ['boolean'],
],
],
Run validation in a command, service provider, or route:
use AshAllenDesign\ConfigValidator\Facades\ConfigValidator;
ConfigValidator::validate('app');
config/config-validator.php (published rulesets).ConfigValidator for quick validation calls.php artisan config:validate for CLI validation.Validation in Bootstrapping:
Add validation to AppServiceProvider’s boot() method to fail fast during application startup:
public function boot()
{
if (!ConfigValidator::validate('app')) {
exit(1); // Or throw an exception
}
}
Dynamic Rulesets: Load rulesets conditionally (e.g., based on environment):
$ruleset = config('app.env') === 'local' ? 'local' : 'production';
ConfigValidator::validate($ruleset);
Custom Rules:
Extend validation with custom rules by implementing AshAllenDesign\ConfigValidator\Contracts\Rule:
use AshAllenDesign\ConfigValidator\Contracts\Rule;
class IsNonEmptyArray implements Rule
{
public function __invoke($value, $attribute, $config)
{
return is_array($value) && !empty($value);
}
}
Register the rule in config/config-validator.php:
'rules' => [
'is_non_empty_array' => \App\Rules\IsNonEmptyArray::class,
],
Validation in Tests:
Use in phpunit.xml or test setup:
public function setUp(): void
{
$this->assertTrue(ConfigValidator::validate('test'));
}
.env validation (e.g., vlucas/phpdotenv) to ensure consistency.php artisan config:validate as a pre-deploy step to catch misconfigurations early.$ruleset = DB::table('config_rulesets')->where('name', 'api')->first();
ConfigValidator::validate(json_decode($ruleset->rules, true));
Overly Strict Rules:
Avoid validating app.key or sensitive values in production rulesets—use environment-specific rulesets instead.
// ❌ Bad: Hardcoded in 'app' ruleset
'app.key' => ['required', 'string'],
// ✅ Good: Environment-specific
'production' => [
'app.key' => ['required', 'string', 'size:32'],
],
Circular Dependencies:
Rules referencing other config values (e.g., mail.driver depending on services.mailgun.key) may cause infinite loops. Use lazy validation or separate rulesets.
Silent Failures: By default, validation throws exceptions. To suppress exceptions and return a boolean:
ConfigValidator::validate('app', false); // Second arg = throw_exception
Detailed Errors: Enable verbose output for debugging:
ConfigValidator::validate('app', false, true); // Third arg = verbose
Outputs a structured error message with failed rules.
Log Validation Results: Wrap validation in a try-catch to log failures:
try {
ConfigValidator::validate('app');
} catch (\AshAllenDesign\ConfigValidator\Exceptions\ConfigValidationException $e) {
\Log::error('Config validation failed: ' . $e->getMessage());
}
Custom Validators:
Extend the Validator class to add pre/post-validation logic:
use AshAllenDesign\ConfigValidator\Validator;
class CustomValidator extends Validator
{
protected function preValidate(array $config, array $rules)
{
// Add logic before validation
}
}
Bind the custom validator in the service provider:
$this->app->bind(
\AshAllenDesign\ConfigValidator\Contracts\Validator::class,
\App\Validators\CustomValidator::class
);
Rule Caching:
Cache compiled rulesets for performance (e.g., in boot()):
if (!cache()->has('config-validator-rules')) {
cache()->put('config-validator-rules', ConfigValidator::getRulesets());
}
Conditional Rules: Use PHP callbacks for dynamic rules:
'database.connections.mysql.host' => function ($value, $config) {
return $config['app.env'] === 'production' ? 'required' : 'nullable';
},
extends key:
'rulesets' => [
'base' => [...],
'production' => [
'extends' => 'base',
'app.debug' => ['boolean', 'false'],
],
],
'services.mailgun.key' => ['required', 'string'],
'services.mailgun.settings' => [
'*.timeout' => ['integer', 'between:1,30'],
],
How can I help you explore Laravel packages today?