Skip to main content
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.
list
array
required
Array mapping field names to rules. Rules can be pipe-separated strings or arrays.
return
Validator
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

required
rule
Field must be present and not empty.
'username' => 'required'
required_with
rule
Field required if any specified fields are present.
'state' => 'required_with:city,zipcode'
exist
rule
Field must exist (allows empty values).
'optional_field' => 'exist'
absent
rule
Field must not be present. Optionally sets default value.
'hidden_field' => 'absent:default_value'

Type Rules

string
rule
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'
integer
rule
Value must be integer or numeric string.
'age' => 'integer'
// Input: "25" → Output: 25 (int)
numeric
rule
Value must be numeric (int or float).
'price' => 'numeric'
// Input: "19.99" → Output: 19.99 (float)
array
rule
Value must be array. Can specify nested validation.
'settings' => [
    'array' => [
        'theme'    => 'required|string',
        'language' => 'required|in:en,ru,de'
    ]
]
checkbox
rule
Validates checkbox input (converts to boolean).
'accept_terms' => 'checkbox'
// Checked: string value → true
// Unchecked: null → false

Constraint Rules

min
rule
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
'tags' => 'array|min:2'
max
rule
Maximum value/length/count. Same usage as min.
'bio' => 'string|max:500'
'rating' => 'integer|max:5'
'files' => 'file:multiple|max:2048'  // 2MB per file
in
rule
Value must be in list.
'role' => 'in:user,moderator,admin'
// Or array format:
'role' => ['in' => ['user', 'moderator', 'admin']]
not_in
rule
Value must NOT be in list.
'username' => 'not_in:admin,root,system'
same
rule
Value must match another field.
'password_confirm' => 'required|same:password'

Pattern Rules

regex
rule
Value must match regex pattern.
'zipcode' => 'regex:/^\d{5}(-\d{4})?$/'
'slug'    => 'regex:/^[a-z0-9-]+$/'
password
rule
Password format validation (must contain space with non-space on both sides).
'passphrase' => 'required|password'

File Rules

file
rule
Validates uploaded files.Single file:
'avatar' => 'file|max:1024'  // Max 1MB
Multiple files:
'attachments' => 'file:multiple|max:2048'
image
rule
Validates uploaded image files.
'photo' => 'image|max:5120'  // Max 5MB
'gallery' => 'image:multiple|max:2048'

Special Rules

token
rule
Validates CSRF token.
'token' => 'token:EditUserProfile'
// With custom lifetime (seconds)
'token' => 'token:3600:EditUserProfile'
referer
rule
Validates and sanitizes referrer URL.
'redirect' => 'referer:Index'
date
rule
Validates date format.
'birthdate' => 'date'

Validation Execution

validation

public function validation(array $raw, bool $strict = false): bool
Validates data against defined rules.
raw
array
required
Raw input data (typically $_POST or $_GET).
strict
bool
default:"false"
If true, fails validation when input contains extra fields not in rules.
return
bool
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.
all
bool
default:"false"
Include null values (fields that failed validation or are optional).
doNotUse
array
default:"[]"
List of field names to exclude from result.
return
array
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.
field
string
required
Field name.
return
bool
True if field is valid.
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.
return
array
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.
return
array
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.
messages
array
required
Array mapping “field.rule” or “field” to custom message.
return
Validator
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.
aliases
array
required
Array mapping field names to display names.
return
Validator
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.
arguments
array
required
Array mapping “field.rule” or “field” to arguments.
return
Validator
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.
validators
array
required
Array mapping rule names to callable validators.
return
Validator
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

User Registration Form

$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
}

Search Form

$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