Summary: in this tutorial, you’ll learn to build a reusable PHP validation library from scratch.
In previous tutorials, you learned how to validate a form field using the filter_input()
and filter_var()
functions. For example, the following sanitizes and validates the email
field in the POST
request:
// validate email
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$inputs['email'] = $email;
if ($email) {
$email = filter_var($email, FILTER_SANITIZE_EMAIL);
if (!$email) {
$errors['email'] = 'Please enter a valid email';
}
} else {
$errors['email'] = 'Please enter an email';
}
Code language: PHP (php)
This code works fine. However, it’s pretty lengthy and not reusable. So let’s build a reusable validation library.
Define validation rules
Each field has one or more validation rules. For example, the email
field is required and must be a valid email address, so the email field has two rules:
- required
The username
is required and between 3 and 255 characters. Also, it should contain only letters and numbers. Therefore, the username
field has three rules:
- required
- between 3 and 20 characters
- alphanumeric
To define rules for fields, you can define a $fields
array like this:
$fields = [
'email'=> 'required | email',
'username' => 'required | alphanumeric | between: 3,255
];
Code language: PHP (php)
Each element in the $fields
array has the key
as the field name and value as the rules. We use the | character to separate two rules.
If a rule has parameters, e.g., between: 3, 25
, we use the :
character to separate the rule name and its parameters. Also, we use the comma ,
to separate two parameters.
We’ll create the following rules:
Rule | Rule name | Parameter | Meaning |
---|---|---|---|
required | required | No | The field is set and not empty |
alphanumeric | alphanumeric | No | The field only contains letters and numbers |
No | The field is a valid email address | ||
secure | secure | No | The field must have between 8 and 64 characters and contain at least one number, one uppercase letter, one lowercase letter, and one special character. This rule is for the password field. |
min: 3 | min | An integer specifies the minimum length of the field | The length of the field must be greater than or equal to the length, e.g., 3 |
max: 255 | max | An integer specifies the maximum length of the field | The length of the field must be less than or equal to the length, e.g., 255 |
same: another_field | same | The name of another field | The field value must be the same as the value of the another_field |
between: min, max | between | min and max are integers that specify the minimum and maximum length of the field | The length of the field must be between min and max. |
unique: table, column | unique | column and table in a relational database. Or field and collection in a NoSQL database | The field value must be unique in the column of the table in a database |
The following example defines the fields with rules:
$fields = [
'firstname' => 'required, max:255',
'lastname' => 'required, max: 255',
'address' => 'required | min: 10, max:255',
'zipcode' => 'between: 5,6',
'username' => 'required | alphanumeric | between: 3,255 | unique: users,username',
'email' => 'required | email | unique: users,email',
'password' => 'required | secure',
'password2' => 'required | same:password'
];
Code language: PHP (php)
The validate() function
The validation library should have the validate()
function that accepts an associative array of data to validate $data
and the $fields
array that contains the validation rules:
function validate(array $data, array $fields)
Code language: PHP (php)
It should return an array that contains the validation errors, in which the key of each element is the field name and the value is the error message:
function validate(array $data, array $fields): array
{
// implementation
}
Code language: PHP (php)
The validate()
function will need to iterate over the $fields
. It loops through rules for each field and validates the value against each rule. If the validation fails, it’ll add an error message to an $errors
array:
function validate(array $data, array $fields) : array
{
$errors = [];
foreach ($fields as $field => $option) {
// get the rules of the field
$rules = split($option);
foreach ($rules as $rule) {
// run a validation rule for each field
}
}
return $errors;
}
Code language: PHP (php)
Since the rules of a field is a string, you need to separate the rules using the |
character. Also, you need to strip all the whitespaces. To do that, you can define an arrow function to:
- First, split a string by a separator.
- Then, trim each item in the result array and return it.
The arrow function will look like this:
$split = fn($str, $separator) => array_map('trim', explode($separator, $str));
Code language: PHP (php)
The arrow function accepts a string and a separator. The explode()
function splits the $str
by the $separator
. The result of the explode()
function is an array of strings.
The array_map()
function executes the trim()
function on each item and returns a new array of items with the whitespaces removed.
The validate() function is updated to include the arrow function as follows:
function validate(array $data, array $fields)
{
$split = fn($str, $separator) => array_map('trim', explode($separator, $str));
$errors = [];
foreach ($fields as $field => $option) {
// get the rules of the field
$rules = $split($option, '|');
foreach ($rules as $rule) {
// run a validation on each rule
}
}
return $errors;
}
Code language: PHP (php)
The $rule
may or may not have parameters. If it has parameters, it’ll contain the :
character. The following code extracts the rule name and its parameters:
if (strpos($rule, ':')) {
[$rule_name, $param_str] = $split($rule, ':');
$params = $split($$param_str, ',');
} else {
$rule_name = trim($rule);
}
Code language: PHP (php)
You use the $split
arrow function in this code to split the rule by the :
character. For example:
between: 3,255
Code language: PHP (php)
will become two strings:
'between'
'3,255'
Code language: PHP (php)
The following uses the array destructuring to assign the first and second elements of the result of the $split
function to the $rule_name
and$param_str
:
[$rule_name, $param_str] = $split($rule, ':');
Code language: PHP (php)
For example, the rule "between : 3, 255"
will result in:
$rule_name = 'between';
$param_str = '3, 255'
Code language: PHP (php)
To get the parameter list, you pass the $param_str
to the $split()
function:
$params = $split($param_str, ',');
Code language: PHP (php)
The validate()
function will look like the following:
function validate(array $data, array $fields): array
{
$errors = [];
$split = fn($str, $separator) => array_map('trim', explode($separator, $str));
foreach ($fields as $field => $option) {
$rules = $split($option, '|');
foreach ($rules as $rule) {
$params = [];
if (strpos($rule, ':')) {
[$rule_name, $param_str] = $split($rule, ':');
$params = $split($param_str, ',');
} else {
$rule_name = trim($rule);
}
}
}
return $errors;
}
Code language: PHP (php)
Now, you have fields and their rule names with parameters.
To execute validation for each rule, you can have a big if-elseif
statement like this:
if($rule_name === 'required') {
} elseif($rule_name === 'email') {
} ...
Code language: PHP (php)
However, this approach has two issues:
- First, a big if-elseif is hard to maintain.
- Second, if you want to add a new rule, you must change the
validate()
function, which is not ideal.
You want the validate() function to be more dynamic so that we don’t need to change the function when you add a new rule later. To do that, you can use the variable functions.
For each rule, you call the validation function dynamically like this:
$rule_name($data, $field, ...$params);
Code language: PHP (php)
The first and second arguments of the validation function are $data
and $field
. The third argument is a list of arguments spread from the array $params
.
For example, if the $params
is [3,255]
, the ...$params
will return 3 and 255.
So the rule 'between: 3, 255'
of the username
with the value "john"
will result in the following function call:
between($data, 'username', 3, 255)
Code language: PHP (php)
To prevent the validation function from collie with the standard function like min
, you can prefix our validation function with the string is_
. For example, the between
rule will execute the is_between
validation function.
The following shows the updated validate()
function:
function validate(array $data, array $fields): array
{
$errors = [];
$split = fn($str, $separator) => array_map('trim', explode($separator, $str));
foreach ($fields as $field => $option) {
$rules = $split($option, '|');
foreach ($rules as $rule) {
$params = [];
if (strpos($rule, ':')) {
[$rule_name, $param_str] = $split($rule, ':');
$params = $split($param_str, ',');
} else {
$rule_name = trim($rule);
}
$fn = 'is_' . $rule_name;
if (is_callable($fn)) {
$pass = $fn($data, $field, ...$params);
}
}
}
return $errors;
}
Code language: PHP (php)
In this validate()
function, you use the is_callable()
function to check if the is_rule_name
is a callable before calling it.
Returning error messages
Each rule should have a specific error message. If validation fails, you need to store the error message in the $error
array. Also, you should be able to return an error message with the parameters.
For example, if the following rule fails:
'username' => 'between: 3, 255'
Code language: PHP (php)
You should return the error message:
The username should be between 3 and 255 characters.
Code language: PHP (php)
To do that, first, you define the default validation error messages:
const DEFAULT_VALIDATION_ERRORS = [
'required' => 'Please enter the %s',
'email' => 'The %s is not a valid email address',
'min' => 'The %s must have at least %s characters',
'max' => 'The %s must have at most %s characters',
'between' => 'The %s must have between %d and %d characters',
'same' => 'The %s must match with %s',
'alphanumeric' => 'The %s should have only letters and numbers',
'secure' => 'The %s must have between 8 and 64 characters and contain at least one number, one upper case letter, one lower case letter and one special character',
'unique' => 'The %s already exists',
];
Code language: PHP (php)
In the DEFAULT_VALIDATION_ERRORS
array, the key is the rule name, while the value is the error message. The error message has %s
or %d
placeholders so that you can use the sprintf()
function to format the error message with parameters like this:
sprintf(DEFAULT_VALIDATION_ERRORS[$rule_name], $field, ...$params);
Code language: PHP (php)
Here’s the validate()
function with error messages:
function validate(array $data, array $fields): array
{
$errors = [];
$split = fn($str, $separator) => array_map('trim', explode($separator, $str));
foreach ($fields as $field => $option) {
$rules = $split($option, '|');
foreach ($rules as $rule) {
$params = [];
if (strpos($rule, ':')) {
[$rule_name, $param_str] = $split($rule, ':');
$params = $split($param_str, ',');
} else {
$rule_name = trim($rule);
}
$fn = 'is_' . $rule_name;
if (is_callable($fn)) {
$pass = $fn($data, $field , ...$params);
if (!$pass) {
$errors[$field] = sprintf(DEFAULT_VALIDATION_ERRORS[$rule_name], $field, ...$params);
}
}
}
}
return $errors;
}
Code language: PHP (php)
Adding custom error messages
The validate()
function uses the default error messages. However, sometimes, you need to pass our custom error message.
For example, you may want to use a message like 'The username is required'
for the required
rule instead of using the default one.
To do that, you can add a third parameter to the validate()
function to store the custom error messages. This parameter is an array of items whose key is the field name and whose value is the error message. For example:
['required' => 'The %s is required']
Code language: PHP (php)
If you pass the custom error messages array to the validate()
function, it will be used instead of the default one.
Here’s the validate()
function with the custom error messages:
function validate(array $data, array $fields, array $messages = []): array
{
$split = fn($str, $separator) => array_map('trim', explode($separator, $str));
// set the validation messages
$validation_errors = array_merge(DEFAULT_VALIDATION_ERRORS, $messages);
$errors = [];
foreach ($fields as $field => $option) {
$rules = $split($option, '|');
foreach ($rules as $rule) {
$params = [];
if (strpos($rule, ':')) {
[$rule_name, $param_str] = $split($rule, ':');
$params = $split($param_str, ',');
} else {
$rule_name = trim($rule);
}
$fn = 'is_' . $rule_name;
if (is_callable($fn)) {
$pass = $fn($data, $field, ...$params);
if (!$pass) {
$errors[$field] = sprintf($validation_errors[$rule_name], $field, ...$params);
}
}
}
}
return $errors;
}
Code language: PHP (php)
In the validate()
function:
First, merge the default error messages with the custom error messages. The custom error message will overwrite the default error messages:
$validation_errors = array_merge(DEFAULT_VALIDATION_ERRORS, $messages);
Code language: PHP (php)
Second, get the error messages from the $validation_errors
instead of the DEFAULT_VALIDATION_ERRORS
array:
$errors[$field] = sprintf($validation_errors[$rule_name], $field, ...$params);
Code language: PHP (php)
Add a custom error message for each field and rule
So far, a custom error message is applied to a specific rule of all fields. For example:
['required' => 'The % is required']
Code language: CSS (css)
And you have two fields:
[
'username' => 'required',
'password' => 'required'
]
Code language: PHP (php)
The custom error message will apply to both username
and password
fields.
Sometimes, you want to apply a custom error message for a specific field. For example, you want the required rule of the username to have a message like:
Please use your username to sign in
Code language: PHP (php)
And the custom error message for the password field is:
Use your password to sign in
Code language: PHP (php)
To do that, you need to enhance the validate()
function:
function validate(array $data, array $fields, array $messages = []): array
Code language: PHP (php)
The $messages
variable will look like the following to support a custom message for a specific rule and field:
[
'required' => 'The %s is required',
'username' => ['required'=> 'Please use your username to sign in']
]
Code language: PHP (php)
The first element will set the error message for the required rule of all fields:
'required' => 'The %s is required'
Code language: PHP (php)
The second element will set the error message for the required rule of the username:
'username' => ['required'=> 'Please use your username to sign in']
Code language: PHP (php)
If the element’s value is a string, it is the error message for a rule of all fields. The key is the rule name, and the value is an error message.
However, if the element’s value is an array, the key is the field name, and the value is an array of rules and error messages.
The following returns an array that contains a list of rules and error messages:
$rule_messages = array_filter($messages, fn($message) => is_string($message));
Code language: PHP (php)
Once having this $rule_messages
array, you can merge it with the default error messages:
$validation_errors = array_merge(DEFAULT_VALIDATION_ERRORS, $rule_messages);
Code language: PHP (php)
The following gets the error message for a field and rule if it exists:
$message[$field][$rule]
Code language: PHP (php)
Otherwise, you can get the error message from the $validation_errors
above:
$validation_errors[$rule_name]
Code language: PHP (php)
The following shows the validate()
function with the new logic for custom error messages:
/**
* Validate
* @param array $data
* @param array $fields
* @param array $messages
* @return array
*/
function validate(array $data, array $fields, array $messages = []): array
{
// Split the array by a separator, trim each element
// and return the array
$split = fn($str, $separator) => array_map('trim', explode($separator, $str));
// get the message rules
$rule_messages = array_filter($messages, fn($message) => is_string($message));
// overwrite the default message
$validation_errors = array_merge(DEFAULT_VALIDATION_ERRORS, $rule_messages);
$errors = [];
foreach ($fields as $field => $option) {
$rules = $split($option, '|');
foreach ($rules as $rule) {
// get rule name params
$params = [];
// if the rule has parameters e.g., min: 1
if (strpos($rule, ':')) {
[$rule_name, $param_str] = $split($rule, ':');
$params = $split($param_str, ',');
} else {
$rule_name = trim($rule);
}
// by convention, the callback should be is_<rule> e.g.,is_required
$fn = 'is_' . $rule_name;
if (is_callable($fn)) {
$pass = $fn($data, $field, ...$params);
if (!$pass) {
// get the error message for a specific field and rule if exists
// otherwise get the error message from the $validation_errors
$errors[$field] = sprintf(
$messages[$field][$rule_name] ?? $validation_errors[$rule_name],
$field,
...$params
);
}
}
}
}
return $errors;
}
Code language: PHP (php)
So far, you have completed the validate()
function. Let’s define the validation function for each rule.
Validation functions
Each validation function must have the following signature:
function validation_function(array $data, string $field, ....$params) : bool
Code language: PHP (php)
required rule
The following is_required()
function returns true if the value is set and not empty:
function is_required(array $data, string $field): bool
{
return isset($data[$field]) && trim($data[$field]) !== '';
}
Code language: PHP (php)
email rule
The following is_email()
function returns true if the value is a valid email address:
function is_email(array $data, string $field): bool
{
if (empty($data[$field])) {
return true;
}
return filter_var($data[$field], FILTER_VALIDATE_EMAIL);
}
Code language: PHP (php)
If $data[$field]
is not set or empty, the is_email()
function also returns true
.
min rule
The following is_min()
function returns true if the field value’s length is greater than or equal to $min:
function is_min(array $data, string $field, int $min): bool
{
if (!isset($data[$field])) {
return true;
}
return mb_strlen($data[$field]) >= $min;
}
Code language: PHP (php)
max rule
The following is_max()
function returns true if the field value length is less than or equal to $max:
function is_max(array $data, string $field, int $max): bool
{
if (!isset($data[$field])) {
return true;
}
return mb_strlen($data[$field]) <= $max;
}
Code language: PHP (php)
between rule
The following is_between()
function returns true
if the field value’s length is between $min
and $max
:
function is_between(array $data, string $field, int $min, int $max): bool
{
if (!isset($data[$field])) {
return true;
}
$len = mb_strlen($data[$field]);
return $len >= $min && $len <= $max;
}
Code language: PHP (php)
alphanumeric rule
The is_alphanumeric()
returns true if the field value contains only letters or characters:
function is_alphanumeric(array $data, string $field): bool
{
if (!isset($data[$field])) {
return true;
}
return ctype_alnum($data[$field]);
}
Code language: PHP (php)
same rule
The is_same()
function returns true
if the field value is the same as the other field’s value:
function is_same(array $data, string $field, string $other): bool
{
if (isset($data[$field], $data[$other])) {
return $data[$field] === $data[$other];
}
if (!isset($data[$field]) && !isset($data[$other])) {
return true;
}
return false;
}
Code language: PHP (php)
secure rule
The is_secure()
returns true if the field value must have between 8 and 64 characters and contain at least one number, one upper case letter, one lower case letter, and one special character:
function is_secure(array $data, string $field): bool
{
if (!isset($data[$field])) {
return false;
}
$pattern = "#.*^(?=.{8,64})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*\W).*$#";
return preg_match($pattern, $data[$field]);
}
Code language: PHP (php)
unique rule
For the unique
rule, you need a database connection and select the value from the $column
of a $table
specified in the rule’s parameters.
First, create a new file called database.php
in the config
folder and add the following constants:
<?php
const DB_HOST = 'localhost';
const DB_NAME = 'auth';
const DB_USER = 'root';
const DB_PASSWORD = '';
Code language: PHP (php)
Second, load the config/database.php
and define a function to connect to the database:
function db()
{
static $pdo;
if (!$pdo) {
$pdo = connect(DB_HOST, DB_NAME, DB_USER, DB_PASSWORD);
}
return $pdo;
}
Code language: PHP (php)
The following is_unique()
function returns true if the value is unique is the $column
of the $table
:
function is_unique(array $data, string $field, string $table, string $column): bool
{
if (!isset($data[$field])) {
return true;
}
$sql = "SELECT $column FROM $table WHERE $column = :value";
$stmt = db()->prepare($sql);
$stmt->bindValue(":value", $data[$field]);
$stmt->execute();
return $stmt->fetchColumn() === false;
}
Code language: PHP (php)
Putting it all together
The following shows all functions in the validation library:
<?php
require __DIR__ . '/../config/database.php';
const DEFAULT_VALIDATION_ERRORS = [
'required' => 'Please enter the %s',
'email' => 'The %s is not a valid email address',
'min' => 'The %s must have at least %s characters',
'max' => 'The %s must have at most %s characters',
'between' => 'The %s must have between %d and %d characters',
'same' => 'The %s must match with %s',
'alphanumeric' => 'The %s should have only letters and numbers',
'secure' => 'The %s must have between 8 and 64 characters and contain at least one number, one upper case letter, one lower case letter and one special character',
'unique' => 'The %s already exists',
];
/**
* Validate
* @param array $data
* @param array $fields
* @param array $messages
* @return array
*/
function validate(array $data, array $fields, array $messages = []): array
{
// Split the array by a separator, trim each element
// and return the array
$split = fn($str, $separator) => array_map('trim', explode($separator, $str));
// get the message rules
$rule_messages = array_filter($messages, fn($message) => is_string($message));
// overwrite the default message
$validation_errors = array_merge(DEFAULT_VALIDATION_ERRORS, $rule_messages);
$errors = [];
foreach ($fields as $field => $option) {
$rules = $split($option, '|');
foreach ($rules as $rule) {
// get rule name params
$params = [];
// if the rule has parameters e.g., min: 1
if (strpos($rule, ':')) {
[$rule_name, $param_str] = $split($rule, ':');
$params = $split($param_str, ',');
} else {
$rule_name = trim($rule);
}
// by convention, the callback should be is_<rule> e.g.,is_required
$fn = 'is_' . $rule_name;
if (is_callable($fn)) {
$pass = $fn($data, $field, ...$params);
if (!$pass) {
// get the error message for a specific field and rule if exists
// otherwise get the error message from the $validation_errors
$errors[$field] = sprintf(
$messages[$field][$rule_name] ?? $validation_errors[$rule_name],
$field,
...$params
);
}
}
}
}
return $errors;
}
/**
* Return true if a string is not empty
* @param array $data
* @param string $field
* @return bool
*/
function is_required(array $data, string $field): bool
{
return isset($data[$field]) && trim($data[$field]) !== '';
}
/**
* Return true if the value is a valid email
* @param array $data
* @param string $field
* @return bool
*/
function is_email(array $data, string $field): bool
{
if (empty($data[$field])) {
return true;
}
return filter_var($data[$field], FILTER_VALIDATE_EMAIL);
}
/**
* Return true if a string has at least min length
* @param array $data
* @param string $field
* @param int $min
* @return bool
*/
function is_min(array $data, string $field, int $min): bool
{
if (!isset($data[$field])) {
return true;
}
return mb_strlen($data[$field]) >= $min;
}
/**
* Return true if a string cannot exceed max length
* @param array $data
* @param string $field
* @param int $max
* @return bool
*/
function is_max(array $data, string $field, int $max): bool
{
if (!isset($data[$field])) {
return true;
}
return mb_strlen($data[$field]) <= $max;
}
/**
* @param array $data
* @param string $field
* @param int $min
* @param int $max
* @return bool
*/
function is_between(array $data, string $field, int $min, int $max): bool
{
if (!isset($data[$field])) {
return true;
}
$len = mb_strlen($data[$field]);
return $len >= $min && $len <= $max;
}
/**
* Return true if a string equals the other
* @param array $data
* @param string $field
* @param string $other
* @return bool
*/
function is_same(array $data, string $field, string $other): bool
{
if (isset($data[$field], $data[$other])) {
return $data[$field] === $data[$other];
}
if (!isset($data[$field]) && !isset($data[$other])) {
return true;
}
return false;
}
/**
* Return true if a string is alphanumeric
* @param array $data
* @param string $field
* @return bool
*/
function is_alphanumeric(array $data, string $field): bool
{
if (!isset($data[$field])) {
return true;
}
return ctype_alnum($data[$field]);
}
/**
* Return true if a password is secure
* @param array $data
* @param string $field
* @return bool
*/
function is_secure(array $data, string $field): bool
{
if (!isset($data[$field])) {
return false;
}
$pattern = "#.*^(?=.{8,64})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*\W).*$#";
return preg_match($pattern, $data[$field]);
}
/**
* Connect to the database and returns an instance of PDO class
* or false if the connection fails
*
* @return PDO
*/
function db(): PDO
{
static $pdo;
// if the connection is not initialized
// connect to the database
if (!$pdo) {
$pdo = new PDO(
sprintf("mysql:host=%s;dbname=%s;charset=UTF8", DB_HOST, DB_NAME),
DB_USER,
DB_PASSWORD,
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
}
return $pdo;
}
/**
* Return true if the $value is unique in the column of a table
* @param array $data
* @param string $field
* @param string $table
* @param string $column
* @return bool
*/
function is_unique(array $data, string $field, string $table, string $column): bool
{
if (!isset($data[$field])) {
return true;
}
$sql = "SELECT $column FROM $table WHERE $column = :value";
$stmt = db()->prepare($sql);
$stmt->bindValue(":value", $data[$field]);
$stmt->execute();
return $stmt->fetchColumn() === false;
}
Code language: PHP (php)
Testing the validation library
To test the unique
rule, you need to create a new database and a table with the username
field, for example.
First, create a new database called auth
:
CREATE DATABASE auth;
Code language: SQL (Structured Query Language) (sql)
Second, create a new users
table:
CREATE TABLE users(
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
email VARCHAR(300) NOT NULL UNIQUE
);
Code language: SQL (Structured Query Language) (sql)
Note that for testing purposes, we don’t need to have the password
field.
Third, insert a row into the users
table:
INSERT INTO users(username, email)
VALUES('bob', '[email protected]');
Code language: SQL (Structured Query Language) (sql)
The following example uses the validate()
function to run a test:
<?php
require __DIR__ . '/validation.php';
$data = [
'firstname' => '',
'username' => 'bob',
'address' => 'This is my address',
'zipcode' => '999',
'email' => 'jo@',
'password' => 'test123',
'password2' => 'test',
];
$fields = [
'firstname' => 'required | max:255',
'lastname' => 'required | max: 255',
'address' => 'required | min: 10, max:255',
'zipcode' => 'between: 5,6',
'username' => 'required | alphanumeric | between: 3,255 | unique: users,username',
'email' => 'required | email | unique: users,email',
'password' => 'required | secure',
'password2' => 'required | same:password'
];
$errors = validate($data, $fields, [
'required' => 'The %s is required',
'password2' => ['same'=> 'Please enter the same password again']]
);
print_r($errors);
Code language: PHP (php)
Output:
Array
(
[firstname] => The firstname is required
[lastname] => The lastname is required
[zipcode] => The zipcode must have between 5 and 6 characters
[username] => The username already exists
[email] => The email is not a valid email address
[password] => The password must have between 8 and 64 characters and contain at least one number, one upper case letter, one lower case letter and o
ne special character
[password2] => Please enter the same password again
)
Code language: PHP (php)
Adding a new validation rule
To add a new rule, you need to do two things:
First, add a default error message to the DEFAULT_VALIDATION_ERRORS
array.
const DEFAULT_VALIDATION_ERRORS = [
// ...
new_rule => "Error message for the new rule"
];
Code language: JavaScript (javascript)
Second, define a validation function with the following signature:
function is_new_rule(array $data, string $field, ....$params) : bool
Code language: PHP (php)
In this tutorial, you have learned how to build a reusable validation library in PHP.