vlucas/valitron
Valitron is a lightweight, dependency-free PHP validation library with simple, readable rules. Validate arrays like $_POST in one call, get structured errors, and extend with custom rules and callbacks—minimal code, well tested, and framework-agnostic.
Installation:
composer require vlucas/valitron
No dependencies, no configuration—just include the autoloader.
First Use Case:
Validate a simple form submission (e.g., $_POST data):
use Valitron\Validator;
$v = new Validator($_POST);
$v->rule('required', ['name', 'email']);
$v->rule('email', 'email');
if ($v->validate()) {
// Process valid data
} else {
// Handle errors: $v->errors()
}
Where to Look First:
required, email, date).user.address.city).$v->errors() returns a structured array).Request Handling: Use middleware or a service to validate incoming requests early (e.g., API payloads, form submissions).
// In a Laravel controller
public function store(Request $request) {
$v = new Validator($request->all());
$v->rules([
'title' => 'required|lengthBetween:5,100',
'content' => 'required',
'published_at' => 'date|dateAfter:today'
]);
if (!$v->validate()) {
return response()->json(['errors' => $v->errors()], 422);
}
// Proceed with logic
}
Reusable Validation Logic:
Create a ValidatorService to encapsulate common rules:
class UserValidator {
public function validate(array $data): bool {
$v = new Validator($data);
$v->rules([
'email' => 'required|email|emailDNS',
'password' => 'required|lengthMin:8',
'role' => 'in:admin,user,guest'
]);
return $v->validate();
}
}
Dynamic Validation:
Use requiredWith, requiredWithout, or custom callbacks for conditional logic:
$v->rules([
'requiredWith' => [['password', 'email']], // Password required if email exists
'requiredWithout' => [['token', 'email']], // Token required if no email
'equals' => [['password', 'confirm_password']]
]);
Custom Callbacks: Extend Valitron with custom rules (e.g., for Laravel-specific logic):
Validator::extend('activeUser', function($field, $value, array $params) {
return User::where('email', $value)->where('active', true)->exists();
});
$v->rule('activeUser', 'email');
Arrays and Objects: Validate nested structures using dot notation:
$data = ['user' => ['name' => 'John', 'address' => ['city' => 'NY']]];
$v->rules([
'required' => ['user.name', 'user.address.city'],
'alpha' => ['user.name'],
'lengthMax' => ['user.address.city', 50]
]);
Array Iteration: Validate all items in an array (e.g., tags, items):
$data = ['tags' => ['laravel', 'php', 'validation']];
$v->rule('lengthMax', 'tags.*', 20); // All tags must be ≤20 chars
$errors = $v->errors();
// Example output:
// [
// 'email' => ['The email field is required.'],
// 'password' => ['The password must be at least 8 characters.']
// ]
$v->rule('required', 'email')->message('Please provide a valid email address.');
FormRequest for seamless validation:
use Valitron\Validator;
class StoreUserRequest extends FormRequest {
public function validate() {
$validator = new Validator($this->all());
$validator->rules([
'name' => 'required|alphaNum|lengthMax:50',
'email' => 'required|email|unique:users'
]);
if (!$validator->validate()) {
throw new \Exception('Validation failed');
}
return true;
}
}
return response()->json([
'success' => false,
'errors' => collect($v->errors())->flatten()->toArray()
], 422);
Case Sensitivity in Dot Notation:
user.Name ≠ user.name. Valitron uses strict key matching.array_change_key_case($data, CASE_LOWER)).Floating-Point Precision:
min/max rules may fail with floats due to PHP’s precision limits.$v->rule('min', 'price', 0.00, true); // Third param enables BCMath
Empty Arrays vs. Missing Keys:
required skips missing keys but fails for empty arrays ([]).optional or custom logic:
$v->rule('optional', 'tags'); // Allows empty array
Strict Conditional Rules:
requiredWith/requiredWithout with true (strict) behave differently:
// Non-strict: 'password' required if EITHER 'email' OR 'username' exists.
$v->rule('requiredWith', 'password', ['email', 'username']);
// Strict: 'password' required ONLY if BOTH 'email' AND 'username' exist.
$v->rule('requiredWith', 'password', ['email', 'username'], true);
Custom Rules and Dependencies:
Request or Validator classes (no dependencies).$params:
Validator::extend('uniqueUser', function($field, $value, $params) {
return User::where($field, $value)->where('id', '!=', $params[0])->doesntExist();
});
$v->rule('uniqueUser', 'email', [$user->id]);
Validate Without Throwing Errors:
$v->validate(true) to return false instead of throwing exceptions (useful for testing).Inspect Rules:
dd($v->getRules());
Test Edge Cases:
null, empty strings, and edge values (e.g., 0, false, []):
$v = new Validator(['age' => null]);
$v->rule('integer', 'age');
Reuse Validators:
Avoid Over-Validation:
optional for non-critical fields:
$v->rule('optional|email', 'secondary_email');
Cache Rules:
// config/validation.php
return [
'user' => [
'name' => 'required|alphaNum',
'email' => 'required|email|emailDNS',
],
];
Validator::extend('strongPassword', function($field, $value) {
return preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).
How can I help you explore Laravel packages today?