VALIDATION

Last updated: June 29th 2026

VALIDATION LIBRARY

Validation helper offers a wide range of different set of validation. You can also create your own.

Explore Now

Using the library

Import the validator helper:

use Simple\Validation\Validator as Validate;

Example One

$request->post() is an instance of (Request $request) pass in your controller

Validation long format Example:

$v = new validate;

$post_data = $v->sanitize($request->post()); // You don't have to sanitize, but it's safest to do so.

$v->validation_rules(array(
    	'username'    => 'required|alpha_numeric|max_len,100|min_len,6',
    	'password'    => 'required|max_len,100|min_len,6',
    	'email'       => 'required|valid_email',
    	'gender'      => 'required|exact_len,1|contains,m f',
    	'credit_card' => 'required|valid_cc'
));

$v->filter_rules(array(
    	'username' => 'trim|sanitize_string',
    	'password' => 'trim',
    	'email'    => 'trim|sanitize_email',
    	'gender'   => 'trim',
    	'bio'	   => 'noise_words'
));

$validated_data = $v->run($post_data);

if($validated_data === false) {
    	echo $v->get_readable_errors(true);
} else {
    	print_r($validated_data); // validation successful
}                                 
    

Example two

By calling is_valid statically, You may run validation like this:

Validation Short format Example:


$validated = validate::is_valid($request->post(), array(
    	'street' => 'required|street_address'
));

if($validated === true) {
    	echo "Valid Street Address!";
} else {
    	print_r($validated);
}                         
    

Checking if value exist in the database table

Check if specific value exist:

$v->validation_rules(array(
    	'username'    => 'required|alpha_numeric|max_len,100|min_len,6|unique,users',
    	'password'    => 'required|max_len,100|min_len,6',
    	'email'       => 'required|valid_email|unique,users',
));                       

use unique,table_name as validation rule.

The example above checks if the value of username and email exist is the users table.

Match data-keys against rules-keys

We can check if there is a rule specified for every data-key, by adding an extra parameter to the run method.

$v->run($_POST, true);

If it doesn't match the output will be:

There is no validation rule for <span class=\"$field_class\">$field</span>

Return Values

run() returns one of two types:

  • ARRAY containing the successfully validated and filtered data when the validation is successful
  • BOOLEAN False when the validation has failed

validate() returns one of two types:

  • ARRAY containing key names and validator names when data does not pass the validation.
  • You can use this array along with your language helpers to determine what error message to show.
  • BOOLEAN value of TRUE if the validation was successful.

filter() returns the exact array structure that was parsed as the $input parameter, the only difference would be the filtered data.

AVAILABLE RULES

Here is the complete list of available validation rules:

RuleDescription
requiredEnsures the value exists and is not empty
required_fileEnsures a file was successfully uploaded
valid_emailChecks for a valid email address
max_len,nValue must not exceed n characters
min_len,nValue must be at least n characters
exact_len,nValue must be exactly n characters
between_len,min;maxLength must be between min and max
alphaOnly alpha characters (a-z, international)
alpha_numericAlpha and numeric characters
alpha_dashAlpha, dashes and underscores
alpha_numeric_dashAlpha, numeric, dashes and underscores
alpha_numeric_spaceAlpha, numeric and spaces
alpha_spaceAlpha and spaces
numericValid number or numeric string
integerValid integer
floatValid float
booleanAccepts 1/0, true/false, yes/no, on/off. Use boolean,strict for strict true/false
valid_urlValid URL format
url_existsURL is accessible (DNS check)
valid_ipValid IP address
valid_ipv4Valid IPv4 address
valid_ipv6Valid IPv6 address
valid_ccValid credit card number (MOD10 algorithm)
valid_nameValid human name format
contains,listValue must be in the semicolon-separated list
contains_list,listLike contains but error hides the valid values
doesnt_contain_list,listValue must NOT be in the list
street_addressLikely a street address (number + letters + space)
ibanValid IBAN
dateValid ISO 8601 date, or date,d/m/Y for custom format
min_age,nDate of birth must be at least n years ago
min_numeric,nNumeric value >= n
max_numeric,nNumeric value <= n
starts,charValue starts with given character(s)
phone_numberValid phone number format
regex,/pattern/Custom regex validation
valid_json_stringValid JSON string
valid_array_size_greater,nArray size >= n
valid_array_size_lesser,nArray size <= n
valid_array_size_equal,nArray size == n
guidv4Valid GUID v4
equalsfield,otherValue must equal another field's value
extension,ext1;ext2File extension must match
strong_passwordMust contain uppercase, lowercase, number, and special character
jwt_tokenValid JWT token format
hash,algoValid hash format for given algorithm
no_sql_injectionDetect common SQL injection patterns
no_xssEnhanced XSS detection
uuidValid UUID (any version)
base64Valid base64 encoded data
hex_colorValid hex color code (e.g. #FF5733)
rgb_colorValid RGB color format
timezoneValid timezone identifier
language_codeValid ISO 639 language code
country_codeValid ISO 3166 country code
currency_codeValid ISO 4217 currency code
mac_addressValid MAC address
domain_nameValid domain name (without protocol)
port_numberValid port (1-65535)
social_handleValid social media handle
latitudeValid latitude (-90 to 90)
longitudeValid longitude (-180 to 180)
postal_code,countryValid postal code for given country
coordinatesValid lat,lng coordinates
future_dateDate must be in the future
past_dateDate must be in the past
business_dayDate must be Monday-Friday
valid_timeValid HH:MM:SS or HH:MM format
date_range,start;endDate must fall within range
evenNumber must be even
oddNumber must be odd
primeNumber must be prime
word_count,min,N,max,MWord count within range
camel_caseValid camelCase format
snake_caseValid snake_case format
url_slugValid URL slug format

AVAILABLE FILTERS

Built-in filters:

FilterDescription
sanitize_stringRemove HTML tags and encode special characters
urlencodeURL-encode the string
htmlencodeEncode HTML entities
sanitize_emailRemove illegal email characters
sanitize_numbersRemove non-numeric characters
sanitize_floatsRemove non-float characters
trimStrip whitespace from both ends
noise_wordsRemove common English noise words
rmpunctuationRemove punctuation characters
basic_tagsStrip all but basic HTML tags
whole_numberConvert to integer
ms_word_charactersConvert MS Word special chars to web-safe
lower_caseConvert to lowercase
upper_caseConvert to uppercase
slugConvert to URL-friendly slug
booleanConvert to boolean (true/false)

Filters can also be any PHP function that returns a string, e.g. base64_encode, md5, sha1, json_encode, etc.

Creating your own validators and filters

Adding custom validators and filters is made easy by using callback functions.


     /*
         Create a custom validation rule named "is_object".
         The callback receives 4 arguments:
         The field, the input array, any rule parameters, and the field value.
         It should return a boolean indicating whether the value is valid.
      */
     validate::add_validator("is_object", function($field, $input, $params = [], $value = null) {
         return is_object($input[$field]);
     });
     
     /*
         Create a custom filter named "upper".
         The callback function receives two arguments:
         The value to filter, and any parameters used in the filter rule. It should returned the filtered value.
      */
     validate::add_filter("upper", function($value, $params = []) {
         return strtoupper($value);
     });                 
    

Alternately, you can simply create your own rules by creating or adding in the Validator class helper.


class MyValidator extends \Simple\Validation\Validator
{
    protected function filter_myfilter($value, array $params = [])
    {
        // ...
    }

    protected function validate_myvalidator($field, array $input, array $params = [], $value = null)
    {
        // ...
    }
}              
    

Remember to create protected methods with the correct parameter types and parameter counts.

  • For filter methods, prepend the method name with "filter_".
  • For validator methods, prepend the method name with "validate_".

Customize Validation Error Messages

You can override error messages at three levels:

  • Globally — affects every use of a rule via Validate::set_error_message()
  • Per-field, per-rule — overrides for specific field/rule combinations via $v->set_fields_error_messages()
  • Inline — in the is_valid() third argument

Available Placeholders

PlaceholderReplaced WithExample
{field}Field name (or readable name if set)username
{param}All parameters joined by comma3, 100
{param[0]}First parameter3
{param[1]}Second parameter100

Per-Field Custom Messages


use Simple\Validation\Validator as Validate;

$v = new Validate;

$v->validation_rules([
    'username' => 'required|alpha_numeric|between_len,3;20',
    'email'    => 'required|valid_email',
    'age'      => 'required|integer|min_numeric,18',
    'password' => 'required|strong_password'
]);

$v->set_fields_error_messages([
    'username' => [
        'required'    => 'Please choose a username',
        'alpha_numeric' => 'Usernames can only contain letters and numbers',
        'between_len' => 'Username must be between {param[0]} and {param[1]} characters'
    ],
    'email' => [
        'required'   => 'An email address is required',
        'valid_email' => 'Enter a valid email address'
    ],
    'age' => [
        'required'    => 'Please enter your age',
        'integer'     => 'Age must be a whole number',
        'min_numeric' => 'You must be at least {param} years old'
    ],
    'password' => [
        'required'        => 'Choose a password',
        'strong_password' => 'Password needs uppercase, lowercase, number, and special character'
    ]
]);

$data = [
    'username' => 'ab',
    'email'    => 'notanemail',
    'age'      => 15,
    'password' => 'weak'
];

$validated = $v->run($data);
// Returns false — errors use the custom messages above

$errors = $v->get_readable_errors(true);
// "Please choose a username" (not "The Username field is required")
// "Usernames can only contain letters and numbers"

Global Error Message Override


use Simple\Validation\Validator as Validate;

// Override globally — affects ALL fields using these rules
Validate::set_error_message('required', 'Oops! {field} cannot be empty.');
Validate::set_error_message('valid_email', '{field} is not a valid email address.');
Validate::set_error_message('min_len', '{field} needs at least {param} characters.');

// Set multiple at once
Validate::set_error_messages([
    'max_len'    => '{field} cannot exceed {param} characters.',
    'min_numeric' => '{field} must be at least {param}.',
    'max_numeric' => '{field} cannot be more than {param}.'
]);

// Now all validations use these messages
$data = ['name' => '', 'email' => 'bad'];
$rules = ['name' => 'required|min_len,2', 'email' => 'required|valid_email'];
$validated = Validate::is_valid($data, $rules);

$errors = Validate::get_instance()->get_readable_errors(true);
// "Oops! name cannot be empty."
// "email is not a valid email address."

Inline with is_valid() Shorthand


use Simple\Validation\Validator as Validate;

$data = [
    'username' => '',
    'email'    => 'bad-email',
    'age'      => 16
];

$rules = [
    'username' => 'required|alpha_numeric|min_len,3',
    'email'    => 'required|valid_email',
    'age'      => 'required|integer|min_numeric,18'
];

$messages = [
    'username' => [
        'required' => 'Pick a username',
        'min_len'  => 'Username needs at least {param[0]} characters'
    ],
    'email' => [
        'required'    => 'Email is required',
        'valid_email' => 'Enter a valid email'
    ],
    'age' => [
        'required'    => 'Enter your age',
        'min_numeric' => 'Must be {param} or older'
    ]
];

$validated = Validate::is_valid($data, $rules, $messages);

if ($validated !== true) {
    // $validated = ['username' => ['Pick a username'], 'email' => ...]
    foreach ($validated as $field => $errors) {
        echo "$field: " . implode(', ', $errors) . "\n";
    }
}

Setting Readable Field Names


use Simple\Validation\Validator as Validate;

// Map field keys to human-readable labels
Validate::set_field_name('usr', 'Username');
Validate::set_field_name('pwd', 'Password');
Validate::set_field_name('email_addr', 'Email Address');

// Or set multiple at once
Validate::set_field_names([
    'usr'        => 'Username',
    'pwd'        => 'Password',
    'email_addr' => 'Email Address',
    'dob'        => 'Date of Birth'
]);

// Now default error messages use these instead of the raw key
$data = ['usr' => '', 'pwd' => '12'];
$rules = ['usr' => 'required|min_len,3', 'pwd' => 'required|min_len,8'];
$validated = Validate::is_valid($data, $rules);

$errors = Validate::get_instance()->get_readable_errors(true);
// "The Username field is required"
// "The Password field needs to be at least 8 characters"

Complete Example — Registration with Custom Messages


use Simple\Validation\Validator as Validate;

// Set readable field names
Validate::set_field_names([
    'first_name' => 'First Name',
    'last_name'  => 'Last Name',
    'email'      => 'Email Address',
    'age'        => 'Age',
    'dob'        => 'Date of Birth',
    'website'    => 'Website URL'
]);

$v = new Validate;

$v->validation_rules([
    'first_name' => 'required|alpha_space|min_len,2|max_len,50',
    'last_name'  => 'required|alpha_space|min_len,2|max_len,50',
    'email'      => 'required|valid_email',
    'age'        => 'required|integer|min_numeric,13|max_numeric,120',
    'dob'        => 'required|date|past_date|min_age,13',
    'website'    => 'valid_url',
    'password'   => 'required|strong_password',
    'terms'      => 'required|boolean,strict'
]);

// Per-field custom error messages
$v->set_fields_error_messages([
    'first_name' => [
        'required'   => 'Please enter your first name',
        'alpha_space' => 'First name can only contain letters and spaces',
        'min_len'    => 'First name must be at least {param[0]} characters'
    ],
    'email' => [
        'required'    => 'An email address is required',
        'valid_email' => 'Enter a valid email address'
    ],
    'age' => [
        'min_numeric' => 'You must be at least {param} years old',
        'max_numeric' => 'Age cannot exceed {param}'
    ],
    'dob' => [
        'date'      => 'Enter a valid date (YYYY-MM-DD)',
        'past_date' => 'Date of birth must be in the past',
        'min_age'   => 'You must be at least {param} years old'
    ],
    'password' => [
        'strong_password' => 'Password must have uppercase, lowercase, a number, and a special character'
    ],
    'terms' => [
        'required' => 'You must accept the terms and conditions',
        'boolean'  => 'Please check the agreement box'
    ]
]);

$data = [
    'first_name' => 'J',
    'last_name'  => 'Doe',
    'email'      => 'not-an-email',
    'age'        => 10,
    'dob'        => '2020-01-01',
    'website'    => 'not-a-url',
    'password'   => 'weak',
    'terms'      => 'no'
];

$validated = $v->run($data);

if ($validated === false) {
    echo $v->get_readable_errors(true);
} else {
    print_r($validated);
}

Validating file fields


$is_valid = validate::is_valid(array_merge($request->post(),$request->file_array()), array(
    	'title' => 'required|alpha_numeric',
    	'image' => 'required_file|extension,png;jpg'
));

if($is_valid === true) {
    	// continue
} else {
    	print_r($is_valid);
}          
    

Date & Time Validation

The library provides several validators for dates, times, and age checks. Below are comprehensive examples covering the most common scenarios.

Basic Date Validation


use Simple\Validation\Validator as Validate;

// Validate ISO 8601 date (Y-m-d)
$data = ['published' => '2025-01-15'];
$rules = ['published' => 'date'];
$result = Validate::is_valid($data, $rules);
// true

// Custom format
$data = ['published' => '15/01/2025'];
$rules = ['published' => 'date,d/m/Y'];
$result = Validate::is_valid($data, $rules);
// true

// Invalid date
$data = ['published' => 'not-a-date'];
$result = Validate::is_valid($data, $rules);
// false

// Invalid for format
$data = ['published' => '2025-01-15'];
$rules = ['published' => 'date,d/m/Y'];
$result = Validate::is_valid($data, $rules);
// false — "2025-01-15" is not valid for d/m/Y

Age Verification


// Minimum age (date of birth must be at least N years ago)
$data = ['dob' => '2000-06-15'];
$rules = ['dob' => 'required|date|min_age,18'];
$result = Validate::is_valid($data, $rules);
// true — born 2000 = 25+ years old

$data = ['dob' => '2020-06-15'];
$result = Validate::is_valid($data, $rules);
// false — only ~5 years old

// With custom date format
$data = ['dob' => '15/06/2000'];
$rules = ['dob' => 'required|date,d/m/Y|min_age,18'];
$result = Validate::is_valid($data, $rules);
// true

Future & Past Dates


// Event must be in the future
$data = ['event_date' => '2030-12-25'];
$rules = ['event_date' => 'required|date|future_date'];
$result = Validate::is_valid($data, $rules);
// true

// Past date — e.g. "date of birth" must be in the past
$data = ['dob' => '1990-01-01'];
$rules = ['dob' => 'required|date|past_date'];
$result = Validate::is_valid($data, $rules);
// true

// Today's date is neither future nor past
$data = ['today' => date('Y-m-d')];
$rules = ['today' => 'date|future_date'];
$result = Validate::is_valid($data, $rules);
// false — today is not in the "future"

$rules = ['today' => 'date|past_date'];
$result = Validate::is_valid($data, $rules);
// false — today is not in the "past"

// With custom format
$data = ['appointment' => '01/12/2030'];
$rules = ['appointment' => 'required|date,d/m/Y|future_date'];
$result = Validate::is_valid($data, $rules);
// true

Date Range


// Date must fall between start and end (inclusive)
$data = ['trip' => '2025-07-15'];
$rules = ['trip' => 'required|date|date_range,2025-06-01;2025-09-01'];
$result = Validate::is_valid($data, $rules);
// true — July 15 is within the range

$data = ['trip' => '2025-05-01'];
$result = Validate::is_valid($data, $rules);
// false — May 1 is before the range

// Booking system: check-in must be within the next 30 days
$start = date('Y-m-d');
$end = date('Y-m-d', strtotime('+30 days'));
$data = ['checkin' => date('Y-m-d', strtotime('+14 days'))];
$rules = ['checkin' => "required|date|date_range,$start;$end"];
$result = Validate::is_valid($data, $rules);
// true

$data = ['checkin' => date('Y-m-d', strtotime('+60 days'))];
$result = Validate::is_valid($data, $rules);
// false — 60 days out is beyond the range

Business Day Check


// Date must be Monday-Friday
$data = ['delivery' => '2025-07-14']; // Monday
$rules = ['delivery' => 'required|date|business_day'];
$result = Validate::is_valid($data, $rules);
// true

$data = ['delivery' => '2025-07-12']; // Saturday
$result = Validate::is_valid($data, $rules);
// false

// Combined: future business day
$rules = ['delivery' => 'required|date|future_date|business_day'];
$result = Validate::is_valid($data, $rules);
// false (Saturday is also not a future date if it's past)

Time Validation


// Valid time formats: HH:MM or HH:MM:SS
$data = ['start' => '09:00'];
$rules = ['start' => 'valid_time'];
$result = Validate::is_valid($data, $rules);
// true

$data = ['start' => '14:30:00'];
$result = Validate::is_valid($data, $rules);
// true

$data = ['start' => '25:00'];
$result = Validate::is_valid($data, $rules);
// false — hour 25 is invalid

// Combined with date
$data = [
    'appointment_date' => '2025-12-01',
    'appointment_time' => '10:30'
];
$rules = [
    'appointment_date' => 'required|date|future_date|business_day',
    'appointment_time' => 'required|valid_time'
];
$result = Validate::is_valid($data, $rules);
// true if 2025-12-01 is a future business day

Date of Birth — Full Real-World Example


// Registration form (long format)
$v = new Validate;

$v->validation_rules([
    'full_name' => 'required|valid_name|max_len,100',
    'email'     => 'required|valid_email',
    'dob'       => 'required|date,d/m/Y|past_date|min_age,18',
    'member_since' => 'date|past_date'
]);

$v->set_fields_error_messages([
    'dob' => [
        'date'      => 'Enter a valid date in DD/MM/YYYY format',
        'past_date' => 'Date of birth must be in the past',
        'min_age'   => 'You must be at least 18 years old'
    ]
]);

$data = [
    'full_name'    => 'Jane Smith',
    'email'        => '[email protected]',
    'dob'          => '15/06/1990',
    'member_since' => '2023-01-01'
];

$validated = $v->run($data);

if ($validated === false) {
    echo $v->get_readable_errors(true);
} else {
    print_r($validated);
}

Event Booking — Full Real-World Example


use Simple\Validation\Validator as Validate;

// Static shorthand format
$data = [
    'event_name'  => 'Summer Conference',
    'event_date'  => '2026-07-15',
    'start_time'  => '09:00',
    'end_time'    => '17:00',
    'reg_deadline' => '2026-06-01'
];

$rules = [
    'event_name'   => 'required|alpha_numeric_space|max_len,200',
    'event_date'   => 'required|date|future_date|business_day',
    'start_time'   => 'required|valid_time',
    'end_time'     => 'required|valid_time',
    'reg_deadline' => 'required|date|date_range,2026-01-01;2026-07-14|past_date'
];

$validated = Validate::is_valid($data, $rules);

if ($validated !== true) {
    foreach ($validated as $field => $errors) {
        echo "$field: " . implode(', ', $errors) . "\n";
    }
}

FormRequest Validation

Type-hint a FormRequest subclass to validate incoming data before the controller method runs. If validation fails, a ValidationException is thrown automatically.

Creating a Form Request

Use the CLI generator or create the class manually:

php cli make:request StoreProductRequest

This generates app/Requests/StoreProductRequest.php:


namespace App\Requests;

use Simple\Validation\FormRequest;

class StoreProductRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'name'  => 'required|min_len:3|max_len:255',
            'price' => 'required|numeric',
            'email' => 'valid_email',
        ];
    }

    public function messages(): array
    {
        return [
            'name' => [
                'required' => 'Product name is required.',
                'min_len'  => 'Product name must be at least 3 characters.',
            ],
        ];
    }

    public function fields(): array
    {
        return [
            'name' => 'Product Name',
        ];
    }
}
                                

Using in a Controller

Type-hint the FormRequest in your controller method. Validation runs automatically before the method body:


use App\Requests\StoreProductRequest;

class ProductController extends Controller
{
    public function store(StoreProductRequest $request)
    {
        // Validation passed — access validated data:
        $data = $request->validated();

        Product::create($data);

        return view('product.show', ['product' => $data]);
    }
}
                                

How it works

The ControllerDispatcher detects FormRequest subclasses via type-hint, creates a fresh instance, calls validate() before the controller method runs. If validation fails, a Simple\Validation\ValidationException is thrown with the error array accessible via $e->errors(). The controller method is never reached.

Accessing Individual Fields

Use input() to retrieve a single validated value:


$name = $request->input('name');  // 'name' from validated data