The Validator class provides comprehensive form validation with built-in rules, custom validators, nested array validation, and detailed error reporting.
Overview
The Validator offers:
Built-in Rules - 20+ validation rules for common scenarios
Custom Validators - Extend with your own validation logic
Nested Validation - Validate complex array structures
Error Management - Detailed error messages with field aliases
CSRF Integration - Automatic token validation
Type Coercion - Convert and sanitize input types
Access via Container: $this->c->Validator (creates new instance each time)
Basic Usage
Validation Workflow
// 1. Get validator instance
$v = $this -> c -> Validator ;
// 2. Add validation rules
$v -> addRules ([
'username' => 'required|string:trim|min:3|max:25' ,
'email' => 'required|string:trim,lower|email' ,
'age' => 'required|integer|min:18|max:120'
]);
// 3. Validate data
$valid = $v -> validation ( $_POST );
if ( $valid ) {
// Get validated data
$data = $v -> getData ();
// Use $data['username'], $data['email'], etc.
} else {
// Get errors
$errors = $v -> getErrors ();
}
Adding Rules
addRules
public function addRules ( array $list ) : Validator
Defines validation rules for fields.
Array mapping field names to rules. Rules can be pipe-separated strings or arrays.
Returns self for method chaining.
String Format:
$v -> addRules ([
'username' => 'required|string:trim|min:3|max:25' ,
'password' => 'required|string|min:8' ,
'age' => 'integer|min:18'
]);
Array Format:
$v -> addRules ([
'email' => [
'required' ,
'string' => 'trim,lower' ,
'regex' => '/ ^ [a-z0-9._%+-] + @[a-z0-9.-] + \. [a-z]{2,} $ /i'
],
'role' => [
'required' ,
'in' => [ 'user' , 'moderator' , 'admin' ]
]
]);
Nested Arrays:
$v -> addRules ([
'profile.name' => 'required|string:trim' ,
'profile.bio' => 'string:trim|max:500' ,
'tags.*' => 'string:trim|max:50' , // Validate each tag
'permissions.*.id' => 'required|integer'
]);
Built-in Validation Rules
Required Rules
Field must be present and not empty.
Field required if any specified fields are present. 'state' => 'required_with:city,zipcode'
Field must exist (allows empty values). 'optional_field' => 'exist'
Field must not be present. Optionally sets default value. 'hidden_field' => 'absent:default_value'
Type Rules
Validates and transforms string values. Actions:
trim - Remove whitespace
lower - Convert to lowercase
spaces - Collapse multiple spaces
linebreaks - Normalize line endings
null - Convert empty to null
empty - Stop validation if empty
'email' => 'string:trim,lower'
'bio' => 'string:trim,linebreaks,spaces'
Value must be integer or numeric string. 'age' => 'integer'
// Input: "25" → Output: 25 (int)
Value must be numeric (int or float). 'price' => 'numeric'
// Input: "19.99" → Output: 19.99 (float)
Value must be array. Can specify nested validation. 'settings' => [
'array' => [
'theme' => 'required|string' ,
'language' => 'required|in:en,ru,de'
]
]
Validates checkbox input (converts to boolean). 'accept_terms' => 'checkbox'
// Checked: string value → true
// Unchecked: null → false
Constraint Rules
Minimum value/length/count. For strings: Character count (or bytes with “bytes” suffix)'username' => 'min:3' // Min 3 characters
'password' => 'min:8 bytes' // Min 8 bytes
For numbers: Minimum value'age' => 'integer|min:18'
For arrays: Minimum elements
Maximum value/length/count. Same usage as min. 'bio' => 'string|max:500'
'rating' => 'integer|max:5'
'files' => 'file:multiple|max:2048' // 2MB per file
Value must be in list. 'role' => 'in:user,moderator,admin'
// Or array format:
'role' => [ 'in' => [ 'user' , 'moderator' , 'admin' ]]
Value must NOT be in list. 'username' => 'not_in:admin,root,system'
Value must match another field. 'password_confirm' => 'required|same:password'
Pattern Rules
Value must match regex pattern. 'zipcode' => 'regex:/^\d{5}(-\d{4})?$/'
'slug' => 'regex:/^[a-z0-9-]+$/'
Password format validation (must contain space with non-space on both sides). 'passphrase' => 'required|password'
File Rules
Validates uploaded files. Single file: 'avatar' => 'file|max:1024' // Max 1MB
Multiple files: 'attachments' => 'file:multiple|max:2048'
Validates uploaded image files. 'photo' => 'image|max:5120' // Max 5MB
'gallery' => 'image:multiple|max:2048'
Special Rules
Validates CSRF token. 'token' => 'token:EditUserProfile'
// With custom lifetime (seconds)
'token' => 'token:3600:EditUserProfile'
Validates and sanitizes referrer URL. 'redirect' => 'referer:Index'
Validation Execution
validation
public function validation ( array $raw , bool $strict = false ) : bool
Validates data against defined rules.
Raw input data (typically $_POST or $_GET).
If true, fails validation when input contains extra fields not in rules.
True if validation passes, false otherwise.
Example:
$v -> addRules ([
'username' => 'required|string:trim|min:3' ,
'email' => 'required|string:trim,lower'
]);
// Normal validation (ignores extra fields)
$valid = $v -> validation ( $_POST );
// Strict validation (fails if $_POST has extra fields)
$valid = $v -> validation ( $_POST , true );
getData
public function getData ( bool $all = false , array $doNotUse = []) : array
Retrieves validated data.
Include null values (fields that failed validation or are optional).
List of field names to exclude from result.
Validated and sanitized data.
Example:
// Get only non-null values
$data = $v -> getData ();
// Get all values including null
$data = $v -> getData ( true );
// Exclude sensitive fields
$data = $v -> getData ( false , [ 'password' , 'token' ]);
getStatus
public function getStatus ( string $field ) : bool
Checks if a specific field passed validation.
Example:
if ( $v -> getStatus ( 'email' )) {
// Email is valid
$email = $v -> email ;
}
Error Handling
getErrors
public function getErrors () : array
Returns all validation errors grouped by type.
Array of errors grouped by message type (FORK_MESS_VLD, FORK_MESS_ERR, etc.).
Example:
$errors = $v -> getErrors ();
// [
// 'v' => [ // FORK_MESS_VLD (validation errors)
// ['The :alias is required', [':alias' => 'Username']],
// ['The :alias maximum is :attr characters', [':alias' => 'Email', ':attr' => '100']]
// ],
// 'e' => [ // FORK_MESS_ERR (error messages)
// ['Bad token', []]
// ]
// ]
getErrorsWithoutType
public function getErrorsWithoutType () : array
Returns errors without type grouping.
Flat array of all error messages.
Example:
$errors = $v -> getErrorsWithoutType ();
// [
// ['The :alias is required', [':alias' => 'Username']],
// ['The :alias maximum is :attr characters', [':alias' => 'Email', ':attr' => '100']],
// ['Bad token', []]
// ]
Customization
addMessages
public function addMessages ( array $messages ) : Validator
Customizes error messages for fields or rules.
Array mapping “field.rule” or “field” to custom message.
Returns self for method chaining.
Example:
$v -> addMessages ([
'username.required' => 'Please enter your username' ,
'username.min' => 'Username must be at least 3 characters' ,
'email' => 'Please enter a valid email address' ,
'password' => [ 'e' , 'Invalid password format' ] // Custom type
]);
addAliases
public function addAliases ( array $aliases ) : Validator
Defines friendly field names for error messages.
Array mapping field names to display names.
Returns self for method chaining.
Example:
$v -> addAliases ([
'username' => 'Username' ,
'email' => 'Email Address' ,
'profile.name' => 'Full Name' ,
'accept_terms' => 'Terms of Service'
]);
// Error will show: "The Email Address is required"
// Instead of: "The email is required"
addArguments
public function addArguments ( array $arguments ) : Validator
Provides additional arguments to validators.
Array mapping “field.rule” or “field” to arguments.
Returns self for method chaining.
Example:
$v -> addArguments ([
'token.token' => [ 'id' => $userId ],
'referer.referer' => [ 'forum_id' => $forumId ]
]);
addValidators
public function addValidators ( array $validators ) : Validator
Registers custom validation rules.
Array mapping rule names to callable validators.
Returns self for method chaining.
Example:
$v -> addValidators ([
'username_available' => function ( $v , $value , $attr ) {
$exists = $this -> c -> DB -> query (
' SELECT 1 FROM ::users WHERE username = ?s' ,
[ $value ]
) -> fetch ();
if ( $exists ) {
$v -> addError ( 'Username already taken' );
}
return $value ;
}
]);
$v -> addRules ([
'username' => 'required|string:trim|username_available'
]);
Real-World Examples
$v = $this -> c -> Validator ;
$v -> addRules ([
'username' => 'required|string:trim|min:3|max:25' ,
'email' => 'required|string:trim,lower|regex:/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i' ,
'password' => 'required|string|min:8' ,
'password_confirm' => 'required|same:password' ,
'accept_terms' => 'required|checkbox' ,
'token' => 'required|token:Register'
]) -> addAliases ([
'username' => 'Username' ,
'email' => 'Email Address' ,
'password' => 'Password' ,
'password_confirm' => 'Password Confirmation' ,
'accept_terms' => 'Terms of Service'
]) -> addMessages ([
'accept_terms.required' => 'You must accept the Terms of Service'
]);
if ( $v -> validation ( $_POST )) {
$data = $v -> getData ( false , [ 'password_confirm' , 'token' ]);
// Create user with $data['username'], $data['email'], $data['password']
} else {
$errors = $v -> getErrors ();
}
Profile Update
$v = $this -> c -> Validator ;
$v -> addRules ([
'profile.name' => 'required|string:trim|max:100' ,
'profile.bio' => 'string:trim,linebreaks,spaces|max:1000' ,
'profile.location' => 'string:trim|max:100' ,
'profile.website' => 'string:trim|regex:/^https?: \\ / \\ /.+$/i' ,
'settings.theme' => 'required|in:light,dark,auto' ,
'settings.language' => 'required|in:en,ru,de,fr' ,
'settings.timezone' => 'required|string' ,
'token' => 'required|token:EditUserProfile' ,
]) -> addArguments ([
'token.token' => [ 'id' => $user -> id ]
]);
if ( $v -> validation ( $_POST )) {
$data = $v -> getData ();
// Update user profile and settings
}
File Upload
$v = $this -> c -> Validator ;
$v -> addRules ([
'avatar' => 'required|image|max:2048' , // Max 2MB
'title' => 'required|string:trim|max:200' ,
'token' => 'required|token:UploadAvatar'
]);
if ( $v -> validation ( $_POST + $_FILES )) {
$data = $v -> getData ();
$file = $data [ 'avatar' ]; // File object
// Process upload
}
$v = $this -> c -> Validator ;
$v -> addRules ([
'keywords' => 'string:trim|min:3|max:100' ,
'author' => 'string:trim|max:50' ,
'forums' => 'array' ,
'forums.*' => 'integer' ,
'sort_by' => 'in:relevance,date,author' ,
'page' => 'integer|min:1'
]);
if ( $v -> validation ( $_GET )) {
$data = $v -> getData ();
// Perform search with filters
}
Nested Array Validation
$v = $this -> c -> Validator ;
$v -> addRules ([
'post.title' => 'required|string:trim|max:200' ,
'post.content' => 'required|string:trim,linebreaks|min:10' ,
'tags' => 'array|max:5' ,
'tags.*' => 'string:trim|max:50' ,
'attachments' => 'file:multiple|max:10240' ,
'poll.question' => 'string:trim|max:200' ,
'poll.options' => 'array|min:2|max:10' ,
'poll.options.*' => 'string:trim|max:100'
]);
if ( $v -> validation ( $_POST + $_FILES )) {
$data = $v -> getData ();
// $data['post']['title']
// $data['post']['content']
// $data['tags'] (array)
// $data['attachments'] (array of File objects)
// $data['poll']['question']
// $data['poll']['options'] (array)
}
Utility Methods
reset
public function reset () : Validator
Resets validator to initial state (clears rules, errors, etc.).
trim
public function trim ( string $value ) : string
Trims UTF-8 whitespace from string.
noValue
public function noValue ( mixed $value , bool $withArray = false ) : bool
Checks if value is empty (null, empty string, or empty array if $withArray is true).
Best Practices
Always Validate CSRF Tokens 'token' => 'required|token:FormAction'
Include token validation in all forms.
Use Type Coercion 'age' => 'integer' // "25" → 25
'email' => 'string:trim,lower' // " USER@EXAMPLE.COM " → "user@example.com"
Let the validator sanitize and convert types.
Provide Friendly Aliases $v -> addAliases ([ 'username' => 'Username' , 'email' => 'Email Address' ]);
Makes error messages user-friendly.
Validate Early if ( ! $v -> validation ( $_POST )) {
return $this -> c -> Message -> message ( $v -> getErrors ());
}
Validate before any business logic.
Exclude Sensitive Data $data = $v -> getData ( false , [ 'password' , 'token' ]);
Don’t include passwords or tokens in returned data.
See Also