Verum PHP is a server-side validation library for PHP that allows you to validate arrays (with file support) with ease. It comes with custom error messages, rules, built-in translations, and zero dependencies.
Server-Side Validation Library for PHP
- Validate arrays (with file support)
- Custom error messages
- Custom rules
- Built-in translations
- Zero dependencies
Install Verum PHP with Composer
composer require sandromiguel/verum-php
Validate a simple registration form (name, email and age)
use Verum\Validator;
$rules = [
'name' => [
'rules' => [
'required',
],
],
'email' => [
'rules' => [
'required',
'email',
],
],
'age' => [
'rules' => [
'numeric',
],
],
];
$validator = new Validator($_POST, $rules);
echo json_encode(
[
'valid' => $validator->validate(),
'errors' => $validator->getErrors(),
]
);
Input:
[
'name' => 'John Doe',
'email' => '[email protected]',
'age' => '20',
]
Output:
{
"valid": true,
"errors": []
}
Input:
[
'name' => '',
'email' => 'some text',
'age' => 'some text',
]
Output:
{
"valid": false,
"errors": {
"name": {
"label": null,
"rules": {
"required": "This field is required."
}
},
"email": {
"label": null,
"rules": {
"email": "This field must be a valid email address."
}
},
"age": {
"label": null,
"rules": {
"numeric": "This field must be numeric."
}
}
}
}
You can use the RuleEnum
class to access all rule names.
use Verum\Validator;
use Verum\Enum\RuleEnum;
$rules = [
'name' => [
'rules' => [
RuleEnum::REQUIRED,
],
],
...
];
$rules = [
'name' => [
'label' => 'Name',
'rules' => [
RuleEnum::REQUIRED,
],
],
...
];
Output:
{
...
"errors": {
"name": {
"label": "Name",
"rules": {
"required": 'The "Name" field is required.'
}
},
...
}
}
$rules = [
'name' => [
'label' => [
'en' => 'Name',
'pt-pt' => 'Nome',
],
'rules' => [
RuleEnum::REQUIRED,
],
],
...
];
Output (pt-pt):
{
...
"errors": {
"name": {
"label": "Nome",
"rules": {
"required": 'O campo "Nome" é obrigatório.'
}
},
...
}
}
You can use some built-in translations:
'en'
-> English (default)'nl-nl'
-> Dutch'pt-pt'
-> Portuguese-Portugal'pt-br'
-> Portuguese-Brazil
$validator = new Validator($_POST, $rules, 'pt-pt');
use Verum\Validator;
use Verum\Enum\LangEnum;
...
$validator = new Validator($_POST, $rules, LangEnum::PT_PT);
- Useful to override the default error message.
- Useful for localization.
...
$validator = new Validator($_POST, $rules);
$validator->addSimpleCustomMessage('min_length', 'Min Length rule custom error message');
...
Output example:
{
...
"errors": {
"name": {
"label": "Name",
"rules": {
"min_length": "Min Length rule custom error message"
}
},
...
}
}
...
$validator = new Validator($_POST, $rules);
$validator->addSimpleCustomMessage('min_length', 'Number of characters detected: {param:1}. Field name: "{param:2}".');
...
Output example:
{
...
"errors": {
"name": {
"label": "Name",
"rules": {
"min_length": 'Number of characters detected: 5. Field name: "Name".'
}
},
...
}
}
...
$validator = new Validator($_POST, $rules);
$validator->addCustomMessage(
'required',
'Custom error message with label for required rule. Label: {param:1}.',
'Custom error message without label for required rule.'
);
...
Output - Field with label:
{
...
"errors": {
"name": {
"label": "Name",
"rules": {
"required": 'Custom error message with label for required rule. Label: Name.'
}
},
...
}
}
Output - Field without label:
{
...
"errors": {
"name": {
"label": null,
"rules": {
"required": "Custom error message without label for required rule."
}
},
...
}
}
...
$validator = new Validator($_POST, $rules);
$validator->addCustomMessages(
[
'min_length' => 'Custom message for the "min_length" rule.',
'required' => 'Custom message for the "required" rule.',
// other messages ...
]
);
...
...
$validator = new Validator($_POST, $rules);
$validator->addCustomMessages(
[
'numeric' => [
'withLabel' => 'Custom message with label for "numeric" rule. Label: {param:1}.',
'withoutLabel' => 'Custom message without label for "numeric" rule.',
],
'min_length' => [
'withLabel' => 'Custom message with label for "min_length" rule. Label: {param:2}, value: {param:1}.',
'withoutLabel' => 'Custom message without label for "min_length" rule. Value: {param:1}.',
],
// other messages ...
]
);
...
With Verum PHP, you can handle multi-name fields more effectively. These are fields that include language identifiers or other variations in their names. For example, if you have fields like title.en
, title.pt
, description.en
, and description.pt
, you can specify rules for them using wildcards.
$rules = [
'title.*' => [
'rules' => [
RuleEnum::REQUIRED,
],
],
'description.*' => [
'rules' => [
RuleEnum::REQUIRED,
RuleEnum::MIN_LENGTH => 10,
],
],
];
$validator = new Validator($_POST, $rules);
// ...
Output example:
{
"valid": false,
"errors": {
"title.en": {
"label": null,
"rules": {
"required": "This field is required."
}
},
"title.pt": {
"label": null,
"rules": {
"required": "This field is required."
}
},
"description.en": {
"label": null,
"rules": {
"required": "This field is required.",
"min_length": "This field must be at least 10 characters long."
}
},
"description.pt": {
"label": null,
"rules": {
"required": "This field is required.",
"min_length": "This field must be at least 10 characters long."
}
}
}
}
You can use your custom validations and inject the error message.
if ($myCustomValidationFail) {
$validator->addError(
'someFieldName',
'Some field name',
['no_duplicate' => 'A user already exists with that username')]
);
// ...
}
- alpha
- alpha_numeric
- between
- between_length
- boolean_value
- contains
- date
- equals
- file_max_size
- file_mime_type
- float_number
- image_max_height
- image_max_width
- image_min_height
- image_min_width
- integer
- ip
- ipv4
- ipv6
- max
- max_length
- min
- min_length
- numeric
- regex
- required
- slug
- url
Checks whether the value contains only alphabetic characters.
$rules = [
'nickname' => [
'label' => 'Nickname',
'rules' => [
RuleEnum::ALPHA,
],
],
];
Value | alpha | alpha + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
❌ | ❌ |
true |
❌ | ❌ |
'text' |
✔️ | ✔️ |
'text with spaces' |
❌ | ❌ |
Checks whether the value contains only alphanumeric characters.
$rules = [
'nickname' => [
'label' => 'Nickname',
'rules' => [
RuleEnum::ALPHA_NUMERIC,
],
],
];
Value | alpha_numeric | alpha_numeric + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
✔️ | ✔️ |
0 |
✔️ | ✔️ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
✔️ | ✔️ |
true |
❌ | ❌ |
'text' |
✔️ | ✔️ |
'text with spaces' |
❌ | ❌ |
Checks whether the value is between two values.
$rules = [
'age' => [
'label' => 'Age',
'rules' => [
RuleEnum::BETWEEN => [12, 29],
],
],
];
Value | between [1, 10] | between [1, 10] + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
✔️ | ✔️ |
true |
❌ | ❌ |
'some text' |
❌ | ❌ |
Checks whether the number of characters of the value is between min and max values.
$rules = [
'nickname' => [
'label' => 'Nickname',
'rules' => [
RuleEnum::BETWEEN_LENGTH => [3, 15],
],
],
];
Value | between_length [5,25] | between_length [5,25] + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
❌ | ❌ |
12345 |
✔️ | ✔️ |
true |
❌ | ❌ |
'text' |
❌ | ❌ |
'text with 23 characters' |
✔️ | ✔️ |
Checks whether the value is a boolean value. Returns true for 1/0, '1'/'0', 'on'/'off', 'yes'/'no', true/false.
$rules = [
'light' => [
'label' => 'Light',
'rules' => [
RuleEnum::BOOLEAN_VALUE,
],
],
];
Value | boolean_value | boolean_value + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
✔️ | ✔️ |
0 |
✔️ | ✔️ |
false |
✔️ | ✔️ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
'1' |
✔️ | ✔️ |
1 |
✔️ | ✔️ |
true |
✔️ | ✔️ |
'text' |
❌ | ❌ |
'on' |
✔️ | ✔️ |
'off' |
✔️ | ✔️ |
'yes' |
✔️ | ✔️ |
'no' |
✔️ | ✔️ |
Checks whether the value is in an array.
$rules = [
'priority' => [
'label' => 'Priority',
'rules' => [
RuleEnum::CONTAINS => ['low', 'high'],
],
],
];
Value | contains ['low','high'] | contains ['low','high'] + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
❌ | ❌ |
true |
❌ | ❌ |
'text' |
❌ | ❌ |
'low' |
✔️ | ✔️ |
'high' |
✔️ | ✔️ |
Checks whether the value is a valid date (Y-m-d) or a custom format.
$rules = [
'dob' => [
'label' => 'Date of birth',
'rules' => [
RuleEnum::DATE,
],
],
];
$rules = [
'dob' => [
'label' => 'Date of birth',
'rules' => [
RuleEnum::DATE => ['d.m.Y'],
],
],
];
Value | date [Y-m-d] | date [Y-m-d] + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
❌ | ❌ |
true |
❌ | ❌ |
'text' |
❌ | ❌ |
'2020-09-30' |
✔️ | ✔️ |
Checks whether the value has a valid email format.
$rules = [
'email' => [
'label' => 'Email',
'rules' => [
RuleEnum::EMAIL,
],
],
];
Value | email + required | |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
❌ | ❌ |
true |
❌ | ❌ |
'text' |
❌ | ❌ |
'[email protected]' |
✔️ | ✔️ |
Checks whether the value is equal to another.
$rules = [
'repeat_password' => [
'label' => 'Repeat Password',
'rules' => [
RuleEnum::EQUALS => ['password'],
],
],
];
Comparison with 'text'
Value | equals | equals + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
❌ | ❌ |
true |
❌ | ❌ |
'text' |
✔️ | ✔️ |
'another text' |
❌ | ❌ |
Checks whether the file size does not exceed a given value.
Enter a value in bytes.
$rules = [
'profile_photo' => [
'label' => 'Profile Photo',
'rules' => [
RuleEnum::FILE_MAX_SIZE => [102400],
],
],
];
Comparison with 102400
bytes
Value | file_max_size | file_max_size + required |
---|---|---|
null |
✔️ | ❌ |
50000 |
✔️ | ✔️ |
150000 |
❌ | ❌ |
Checks whether the file type is allowed.
$rules = [
'profile_photo' => [
'label' => 'Profile Photo',
'rules' => [
RuleEnum::FILE_MIME_TYPE => ['image/png', 'image/jpeg'],
],
],
];
Value | file_mime_type | file_mime_type + required |
---|---|---|
null |
✔️ | ❌ |
image/png |
✔️ | ✔️ |
text/plain |
❌ | ❌ |
Checks whether the value is a floating point number.
$rules = [
'price' => [
'label' => 'Price',
'rules' => [
RuleEnum::FLOAT_NUMBER,
],
],
];
Value | float_number | float_number + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
❌ | ❌ |
12345 |
❌ | ❌ |
123.45 |
✔️ | ✔️ |
true |
❌ | ❌ |
'text' |
❌ | ❌ |
'text with spaces' |
❌ | ❌ |
Checks whether the image height does not exceed a given value.
$rules = [
'profile_photo' => [
'label' => 'Profile Photo',
'rules' => [
RuleEnum::IMAGE_MAX_HEIGHT => [600],
],
],
];
Value | image_max_height | image_max_height + required |
---|---|---|
null |
✔️ | ❌ |
500px | ✔️ | ✔️ |
1000px | ❌ | ❌ |
Checks whether the image width does not exceed a given value.
$rules = [
'profile_photo' => [
'label' => 'Profile Photo',
'rules' => [
RuleEnum::IMAGE_MAX_WIDTH => [1000],
],
],
];
Value | image_max_width | image_max_width + required |
---|---|---|
null |
✔️ | ❌ |
500px | ✔️ | ✔️ |
1500px | ❌ | ❌ |
Checks whether the image height is not less than a given value.
$rules = [
'profile_photo' => [
'label' => 'Profile Photo',
'rules' => [
RuleEnum::IMAGE_MIN_HEIGHT => [300],
],
],
];
Value | image_min_height | image_min_height + required |
---|---|---|
null |
✔️ | ❌ |
100px | ❌ | ❌ |
500px | ✔️ | ✔️ |
Checks whether the image width is not less than a given value.
$rules = [
'profile_photo' => [
'label' => 'Profile Photo',
'rules' => [
RuleEnum::IMAGE_MIN_WIDTH => [500],
],
],
];
Value | image_min_width | image_min_width + required |
---|---|---|
null |
✔️ | ❌ |
400px | ❌ | ❌ |
600px | ✔️ | ✔️ |
Checks whether the value is integer.
$rules = [
'distance' => [
'label' => 'Distance',
'rules' => [
RuleEnum::INTEGER,
],
],
];
Value | numeric | numeric + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
✔️ | ✔️ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
✔️ | ✔️ |
1 |
✔️ | ✔️ |
true |
❌ | ❌ |
'text' |
❌ | ❌ |
Checks whether the value is a valid IP address.
$rules = [
'ip' => [
'label' => 'IP',
'rules' => [
RuleEnum::IP,
],
],
];
Value | ip | ip + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
❌ | ❌ |
true |
❌ | ❌ |
'text' |
❌ | ❌ |
'10.10.10.10' |
✔️ | ✔️ |
'2607:f0d0:1002:51::4' |
✔️ | ✔️ |
Checks whether the value is a valid IPv4 address.
$rules = [
'ipv4' => [
'label' => 'IPv4',
'rules' => [
RuleEnum::IPV4,
],
],
];
Value | ipv4 | ipv4 + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
❌ | ❌ |
true |
❌ | ❌ |
'text' |
❌ | ❌ |
'10.10.10.10' |
✔️ | ✔️ |
'2607:f0d0:1002:51::4' |
❌ | ❌ |
Checks whether the value is a valid IPv6 address.
$rules = [
'ipv6' => [
'label' => 'IPv6',
'rules' => [
RuleEnum::IPV6,
],
],
];
Value | ipv6 | ipv6 + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
❌ | ❌ |
true |
❌ | ❌ |
'text' |
❌ | ❌ |
'10.10.10.10' |
❌ | ❌ |
'2607:f0d0:1002:51::4' |
✔️ | ✔️ |
Checks whether the value does not exceed a given value.
$rules = [
'people' => [
'label' => 'People',
'rules' => [
RuleEnum::MAX => [5],
],
],
];
Value | max | max + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
✔️ | ✔️ |
0 |
✔️ | ✔️ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
✔️ | ✔️ |
1 |
✔️ | ✔️ |
true |
❌ | ❌ |
'text' |
❌ | ❌ |
12345 |
❌ | ❌ |
'12345' |
❌ | ❌ |
Checks whether the number of characters of the value does not exceed a given value.
$rules = [
'nickname' => [
'label' => 'Nickname',
'rules' => [
RuleEnum::MAX_LENGTH => [2],
],
],
];
Value | max_length | max_length + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
✔️ | ✔️ |
0 |
✔️ | ✔️ |
false |
✔️ | ✔️ |
[] |
❌ | ❌ |
-1 |
✔️ | ✔️ |
1 |
✔️ | ✔️ |
true |
✔️ | ✔️ |
'text' |
❌ | ❌ |
12345 |
❌ | ❌ |
'12345' |
❌ | ❌ |
Checks whether the value is not less than a given value.
$rules = [
'people' => [
'label' => 'People',
'rules' => [
RuleEnum::MIN => [2],
],
],
];
Value | min | min + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
❌ | ❌ |
true |
❌ | ❌ |
'text' |
❌ | ❌ |
12345 |
✔️ | ✔️ |
'12345' |
✔️ | ✔️ |
Checks whether the number of characters of the value is not less than a given value.
$rules = [
'nickname' => [
'label' => 'Nickname',
'rules' => [
RuleEnum::MIN_LENGTH => [2],
],
],
];
Value | max_length | max_length + required |
---|---|---|
null |
✔️ | ❌ |
'' |
❌ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
✔️ | ✔️ |
1 |
❌ | ❌ |
true |
❌ | ❌ |
'text' |
✔️ | ✔️ |
12345 |
✔️ | ✔️ |
'12345' |
✔️ | ✔️ |
Checks whether the value is numeric.
$rules = [
'age' => [
'label' => 'Age',
'rules' => [
RuleEnum::NUMERIC,
],
],
];
Value | numeric | numeric + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
✔️ | ✔️ |
0 |
✔️ | ✔️ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
✔️ | ✔️ |
1 |
✔️ | ✔️ |
true |
❌ | ❌ |
'text' |
❌ | ❌ |
Checks whether the value matches a given regular expression.
$rules = [
'path' => [
'label' => 'Path',
'rules' => [
RuleEnum::REGEX => ['/\/client\/[0-9a-f]+$/'],
],
],
];
Validation with the '/\/client\/[0-9a-f]+$/'
pattern
Value | regex | regex + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
❌ | ❌ |
true |
❌ | ❌ |
'text' |
❌ | ❌ |
'/client/77c9e105d1f548b29958f0512967de87' |
✔️ | ✔️ |
'/client/invalid-uuid' |
❌ | ❌ |
Checks whether the value is not empty.
$rules = [
'name' => [
'label' => 'Name',
'rules' => [
RuleEnum::REQUIRED,
],
],
];
Value | required |
---|---|
null |
❌ |
'' |
❌ |
'0' |
✔️ |
0 |
✔️ |
false |
✔️ |
[] |
❌ |
-1 |
✔️ |
1 |
✔️ |
true |
✔️ |
'some text' |
✔️ |
Checks whether the value is a valid Slug (e.g. hello-world_123).
$rules = [
'slug' => [
'label' => 'Slug',
'rules' => [
RuleEnum::SLUG,
],
],
];
Value | slug | slug + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
❌ | ❌ |
true |
❌ | ❌ |
'text' |
✔️ | ✔️ |
'text with spaces' |
❌ | ❌ |
'hello-world_123' |
✔️ | ✔️ |
Checks whether the value is a valid URL.
$rules = [
'url' => [
'label' => 'URL',
'rules' => [
RuleEnum::URL,
],
],
];
Value | url | url + required |
---|---|---|
null |
✔️ | ❌ |
'' |
✔️ | ❌ |
'0' |
❌ | ❌ |
0 |
❌ | ❌ |
false |
❌ | ❌ |
[] |
❌ | ❌ |
-1 |
❌ | ❌ |
1 |
❌ | ❌ |
true |
❌ | ❌ |
'text' |
❌ | ❌ |
'http://www.some-domain.com' |
✔️ | ✔️ |
Want to contribute? All contributions are welcome. Read the contributing guide.
If you have questions tweet me at @sandro_m_m or open an issue.
This project is licensed under the MIT License - see the LICENSE file for details
**~ sharing is caring ~**