Fast, modern PHP request validation and sanitization. Schema-based rules, fail-fast execution, intelligent batching, and 100+ validation rules out of the box.
$validator = Validator::make([
'email' => 'required|email|max:255',
'username' => 'required|alpha_dash|min:3|max:50',
'age' => 'required|integer|min:18',
]);
$result = $validator->validate($data);
if ($result->passes()) {
$clean = $result->validated();
// β
All good!
}- π 103 Built-in Rules - From basic types to complex conditionals and database checks
- π§Ή 50+ Sanitizers - Clean and normalize data before validation
- β‘ Intelligent Batching - Database rules are batched automatically (50x faster)
- π― Fail-Fast Execution - Stops at first error per field for maximum performance
- π¦ Cost-Based Optimization - Rules auto-sorted by complexity (cheap β expensive)
- π Nested Validation - Validate deeply nested arrays with dot notation
- πΎ Database Validation - Built-in
uniqueandexistsrules with custom provider support - π¨ Custom Rules - Simple callbacks or full OOP rule classes
- π PSR-7 Friendly - Works seamlessly with modern PHP frameworks
- π οΈ PHP 8.4+ - Built with modern PHP features
composer require infocyph/reqshieldRequirements: PHP 8.4 or higher
use Infocyph\ReqShield\Validator;
$validator = Validator::make([
'email' => 'required|email|max:255',
'username' => 'required|string|min:3|max:50',
'password' => 'required|min:8',
'password_confirmation' => 'required|same:password',
]);
$result = $validator->validate($data);
if ($result->passes()) {
$validated = $result->validated();
// Process your data...
} else {
$errors = $result->errors();
// Handle validation errors...
}Sanitize before validating:
use Infocyph\ReqShield\Sanitizer;
$clean = [
'email' => Sanitizer::email($input['email']), // '[email protected]'
'username' => Sanitizer::alphaDash($input['username']), // 'john_doe'
'age' => Sanitizer::integer($input['age']), // 25
'bio' => Sanitizer::string($input['bio']), // Strips HTML tags
];
$result = $validator->validate($clean);Or use the helper:
$clean = sanitize(' [email protected] ', 'email'); // '[email protected]'
$clean = sanitize('<b>TEXT</b>', ['string', 'lowercase']); // 'text'ReqShield includes 100+ validation rules covering several common scenarios:
- Basic Types
- Formats
- Strings
- Numbers
- Dates
- Conditionals
- Database
- Files
- Arrays
- Comparison
- Patterns
- Additional
π View Complete Rule Reference
ReqShield includes 50+ sanitizers covering several common scenarios:
- Basic Types
- Case Conversions
- Text Processing
- Special Formats
- Alphanumeric Filters
- Security & HTML
- Encoding
- Array Operations
π View Complete Sanitizer Reference
Validate deeply nested arrays using dot notation:
$validator = Validator::make([
'user.email' => 'required|email',
'user.name' => 'required|min:3',
'user.profile.age' => 'required|integer|min:18',
'user.profile.bio' => 'string|max:500',
])->enableNestedValidation();
$data = [
'user' => [
'email' => '[email protected]',
'name' => 'John Doe',
'profile' => [
'age' => 25,
'bio' => 'Software developer',
],
],
];
$result = $validator->validate($data);Make error messages user-friendly:
$validator->setFieldAliases([
'user_email' => 'Email Address',
'pwd' => 'Password',
'pwd_confirm' => 'Password Confirmation',
]);
// Error: "The Email Address must be a valid email address."
// Instead of: "The user_email must be a valid email address."use Infocyph\ReqShield\Exceptions\ValidationException;
$validator = Validator::make($rules)->throwOnFailure();
try {
$result = $validator->validate($data);
$validated = $result->validated();
} catch (ValidationException $e) {
echo $e->getMessage(); // "Validation failed"
print_r($e->getErrors()); // All errors
echo $e->getErrorCount(); // Number of failed fields
echo $e->getFirstFieldError('email'); // First error for specific field
echo $e->getCode(); // 422
}Use callbacks for quick custom validation:
use Infocyph\ReqShield\Rules\Callback;
$validator = Validator::make([
'code' => [
'required',
new Callback(
callback: fn($value) => $value % 2 === 0,
message: 'The code must be an even number'
),
],
]);Create reusable rule classes:
use Infocyph\ReqShield\Contracts\Rule;
class StrongPassword implements Rule
{
public function passes(mixed $value, string $field, array $data): bool
{
return strlen($value) >= 12
&& preg_match('/[A-Z]/', $value)
&& preg_match('/[a-z]/', $value)
&& preg_match('/[0-9]/', $value)
&& preg_match('/[^A-Za-z0-9]/', $value);
}
public function message(string $field): string
{
return "The {$field} must be at least 12 characters with uppercase, lowercase, number, and special character.";
}
public function cost(): int { return 20; }
public function isBatchable(): bool { return false; }
}
// Usage
$validator = Validator::make([
'password' => ['required', new StrongPassword()],
]);Validate against your database:
use Infocyph\ReqShield\Validator;
use Infocyph\ReqShield\Contracts\DatabaseProvider;
// Implement your database provider
class MyDatabaseProvider implements DatabaseProvider
{
// Implement required methods...
}
Validator::setDatabaseProvider(new MyDatabaseProvider());
$validator = Validator::make([
'email' => 'required|email|unique:users,email',
'category_id' => 'required|exists:categories,id',
]);Benefits:
- π Automatic batching - Multiple checks become one query
- β‘ 50x faster than individual queries
- π― Update support -
unique:users,email,5ignores ID 5
For maximum performance, stop all validation on first error:
$validator = Validator::make($rules)
->setStopOnFirstError(true);
// Stops immediately when any field fails
$result = $validator->validate($data);ReqShield is built for speed:
Rules automatically execute in order of complexity:
- Cheap (< 50): Type checks, empty checks
- Medium (50-99): String operations, regex
- Expensive (100+): Database queries, API calls
Database rules are automatically batched:
// 3 separate rules...
'user_id' => 'exists:users,id',
'email' => 'unique:users,email',
'category_id' => 'exists:categories,id',
// ...become just 2 queries (50x faster!)
// - One batch for exists checks
// - One batch for unique checksStops validating a field on first rule failure:
'email' => 'required|email|max:255'
// If empty β fails on 'required', skips 'email' and 'max:255'Nested validation only activates if you use dot notation. No performance cost for simple flat arrays.
ReqShield is open-sourced software licensed under the MIT license.
If you find ReqShield helpful, please consider giving it a βοΈ on GitHub!
Made with β€οΈ for the PHP community
Documentation β’ Report Bug β’ Request Feature