julienlinard / php-validator
Système de validation avancé pour PHP 8+ avec règles personnalisées, messages multilingues, validation conditionnelle et sanitization
Installs: 159
Dependents: 1
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/julienlinard/php-validator
Requires
- php: >=8.0
Requires (Dev)
- phpunit/phpunit: ^11.5
README
🇫🇷 Read in French | 🇬🇧 Read in English
💝 Support the project
If this package is useful to you, consider becoming a sponsor to support the development and maintenance of this open source project.
A modern and advanced validation system for PHP 8+ with custom rules, multilingual messages, conditional validation, and sanitization.
🚀 Installation
composer require julienlinard/php-validator
Requirements: PHP 8.0 or higher
⚡ Quick Start
Basic Usage
<?php require_once __DIR__ . '/vendor/autoload.php'; use JulienLinard\Validator\Validator; $validator = new Validator(); $data = [ 'email' => 'user@example.com', 'password' => 'password123', 'age' => 25, ]; $rules = [ 'email' => 'required|email', 'password' => 'required|min:8', 'age' => 'required|numeric|min:18', ]; $result = $validator->validate($data, $rules); if ($result->isValid()) { $validated = $result->getValidated(); // Use validated data } else { $errors = $result->getErrors(); // Handle errors }
📋 Features
- ✅ Built-in Rules: 30+ rules including required, email, min, max, numeric, url, in, pattern, date, boolean, between, file, image, size, alpha, alpha_num, alpha_dash, confirmed, ip, ipv4, ipv6, json, uuid, accepted, filled, before, after, different, same
- ✅ Custom Rules: Easy to create and register custom validation rules
- ✅ Multilingual Messages: Support for custom error messages
- ✅ Sanitization: Automatic HTML escaping and trimming
- ✅ Conditional Validation: Skip validation for empty values (except required)
- ✅ Flexible Rules: String format (
required|email|min:5) or array format - ✅ Validation Result: Rich result object with error handling
📖 Documentation
Available Rules
Required
Validates that a field is not empty.
$rules = ['name' => 'required'];
Validates that a field contains a valid email address.
$rules = ['email' => 'email'];
Min / Max
Validates the minimum/maximum length of a string or value.
$rules = [ 'password' => 'min:8', 'title' => 'max:100', ];
Numeric
Validates that a value is numeric.
$rules = ['age' => 'numeric'];
URL
Validates that a field contains a valid URL.
$rules = ['website' => 'url'];
In
Validates that a value is in a list of allowed values.
$rules = ['status' => 'in:active,inactive,pending'];
Pattern
Validates that a value matches a regex pattern.
$rules = ['phone' => 'pattern:/^\+?[1-9]\d{1,14}$/'];
Date
Validates that a field contains a valid date.
$rules = [ 'birthday' => 'date', // Any valid date format 'created_at' => 'date:Y-m-d H:i:s', // Specific format ];
Boolean
Validates that a field is a boolean value. Accepts: true, false, 1, 0, "1", "0", "true", "false", "yes", "no", "on", "off".
$rules = ['is_active' => 'boolean'];
Between
Validates that a value is between two numbers (for numeric) or has a length between two values (for strings).
$rules = [ 'age' => 'between:18,65', // Numeric: between 18 and 65 'title' => 'between:5,100', // String length: between 5 and 100 characters ];
File
Validates that a field is a valid uploaded file.
$rules = [ 'document' => 'file', // Any file 'document' => 'file:10485760', // Max 10MB (in bytes) ]; // For MIME type validation, use array format: $rules = [ 'document' => [ 'file' => [10485760, ['application/pdf', 'application/msword']] ] ];
Image
Validates that a field is a valid image file. Automatically checks MIME type and uses getimagesize() to ensure it's a real image.
$rules = [ 'avatar' => 'image', // Any image 'avatar' => 'image:10485760', // Max 10MB (in bytes) ]; // For specific image types, use array format: $rules = [ 'avatar' => [ 'image' => [10485760, ['image/jpeg', 'image/png']] // Max size first, then allowed types ] ];
Size
Validates that a field has an exact size (for files: bytes, for strings: characters, for numbers: exact value).
$rules = [ 'code' => 'size:6', // String: exactly 6 characters 'file' => 'size:1024', // File: exactly 1024 bytes 'count' => 'size:10', // Number: exactly 10 ];
Alpha
Validates that a field contains only letters (including accented characters).
$rules = ['name' => 'alpha'];
Alpha Num
Validates that a field contains only letters and numbers.
$rules = ['username' => 'alpha_num'];
Alpha Dash
Validates that a field contains only letters, numbers, dashes and underscores.
$rules = ['slug' => 'alpha_dash'];
Confirmed
Validates that a field has a matching confirmation field (e.g., password_confirmation).
$rules = ['password' => 'required|confirmed']; // Requires 'password_confirmation' field to match 'password'
IP Address
Validates that a field is a valid IP address.
$rules = [ 'ip' => 'ip', // IPv4 or IPv6 'ip' => 'ipv4', // IPv4 only 'ip' => 'ipv6', // IPv6 only ];
JSON
Validates that a field contains a valid JSON string.
$rules = ['config' => 'json'];
UUID
Validates that a field is a valid UUID (v1-v5).
$rules = ['id' => 'uuid'];
Accepted
Validates that a field is accepted (yes, on, 1, true). Useful for checkboxes and terms acceptance.
$rules = ['terms' => 'accepted'];
Filled
Validates that a field has a value when present (different from required - allows null if field is not present).
$rules = ['optional_field' => 'filled'];
Before / After
Validates that a date field is before or after another date.
$rules = [ 'start_date' => 'date|before:end_date', 'end_date' => 'date|after:start_date', 'birthday' => 'date|before:today', // or 'before:2024-01-01' ];
Different / Same
Validates that a field is different from or same as another field.
$rules = [ 'new_password' => 'different:old_password', 'password_confirmation' => 'same:password', ];
Multilingual Support
The validator supports multiple languages (French, English, Spanish) out of the box.
// Create validator with a specific locale $validator = new Validator('en'); // English $validator = new Validator('fr'); // French (default) $validator = new Validator('es'); // Spanish // Or change locale after creation $validator = new Validator(); $validator->setLocale('en'); // Get current locale $locale = $validator->getLocale(); // Returns 'en', 'fr', or 'es'
Supported locales:
fr- French (default)en- Englishes- Spanish
Custom Messages
You can customize error messages for specific fields and rules.
$validator = new Validator(); $validator->setCustomMessages([ 'email.email' => 'Please provide a valid email address', 'password.min' => 'Password must be at least :min characters', 'name.required' => 'The name field is required', ]);
Sanitization
By default, the validator automatically sanitizes input data (trims strings, escapes HTML).
$validator = new Validator(); $validator->setSanitize(true); // Default: true $data = ['name' => ' <script>alert("xss")</script> ']; $result = $validator->validate($data, ['name' => 'required']); // The validated value will be sanitized $validated = $result->getValidatedValue('name'); // Result: '<script>alert("xss")</script>'
Custom Rules
You can create and register custom validation rules.
use JulienLinard\Validator\Rules\AbstractRule; use JulienLinard\Validator\Validator; class CustomRule extends AbstractRule { public function getName(): string { return 'custom'; } public function validate(mixed $value, array $params = []): bool { // Your validation logic return $value === 'expected'; } protected function getDefaultMessage(): string { return 'The :field field is invalid.'; } } $validator = new Validator(); $validator->registerRule(new CustomRule()); $rules = ['field' => 'custom'];
Integration with core-php
This package integrates seamlessly with core-php Forms.
use JulienLinard\Core\Controller\Controller; use JulienLinard\Core\Form\FormResult; use JulienLinard\Validator\Validator; class UserController extends Controller { public function store() { $validator = new Validator(); $result = $validator->validate($_POST, [ 'email' => 'required|email', 'password' => 'required|min:8', ]); if (!$result->isValid()) { $formResult = new FormResult(); foreach ($result->getErrors() as $field => $errors) { foreach ($errors as $error) { $formResult->addError(new FormError($error, $field)); } } return $this->view('users/create', ['formResult' => $formResult]); } // Use validated data $validated = $result->getValidated(); // ... } }
📚 API Reference
Validator
validate(array $data, array $rules): ValidationResult
Validates data against rules.
$result = $validator->validate($data, $rules);
setCustomMessages(array $messages): self
Sets custom error messages.
$validator->setCustomMessages([ 'email.email' => 'Invalid email', ]);
setSanitize(bool $sanitize): self
Enables or disables automatic sanitization.
$validator->setSanitize(false);
registerRule(RuleInterface $rule): self
Registers a custom validation rule.
$validator->registerRule(new CustomRule());
ValidationResult
isValid(): bool
Checks if validation passed.
if ($result->isValid()) { // Success }
hasErrors(): bool
Checks if validation failed.
if ($result->hasErrors()) { // Has errors }
getErrors(): array
Gets all errors grouped by field.
$errors = $result->getErrors(); // ['email' => ['Email is required'], 'password' => ['Password too short']]
getFieldErrors(string $field): array
Gets errors for a specific field.
$emailErrors = $result->getFieldErrors('email');
getFirstError(string $field): ?string
Gets the first error for a field.
$firstError = $result->getFirstError('email');
getValidated(): array
Gets all validated and sanitized data.
$validated = $result->getValidated();
getValidatedValue(string $field, mixed $default = null): mixed
Gets a validated value for a specific field.
$email = $result->getValidatedValue('email');
📝 License
MIT License - See the LICENSE file for more details.
🤝 Contributing
Contributions are welcome! Feel free to open an issue or a pull request.
💝 Support
If this package is useful to you, consider becoming a sponsor to support the development and maintenance of this open source project.
Developed with ❤️ by Julien Linard