Data validation
Introduction​
Data validation is a crucial part of any web application. BowPHP provides a simple, elegant, and powerful validation system that lets you easily validate your incoming data.
Basic usage​
The simplest way to use the validator is through the validator() helper function. Here is a simple example:
$data = [
"name" => "John Doe",
"email" => "john@example.com",
"age" => 25
];
$validation = validator($data, [
"name" => "required|min:3|max:50",
"email" => "required|email",
"age" => "required|int"
]);
if ($validation->fails()) {
// Validation failed
$errors = $validation->getMessages();
// Handle the errors
}
Available validation rules​
BowPHP offers a wide range of validation rules to cover most common validation needs.
Basic rules​
| Rule | Description |
|---|---|
required | The field is required |
required_if:field1,field2 | The field is required if the specified fields exist |
nullable | The field may be absent: null, an empty string or an empty array (short-circuits the following rules). false, 0 and 0.0 are real values and are validated by the following rules |
confirmed | The field must match the <name>_confirmation field |
different:field | The field must be different from another field |
same:value | The field must be identical to the specified value |
in:val1,val2,... | The value must be part of the given list |
email | The field must be a valid email address |
min:value | Minimum length of a string, or minimum value of a number sent as a JSON number |
max:value | Maximum length of a string, or maximum value of a number sent as a JSON number |
size:value | Exact length of a string, or exact value of a number sent as a JSON number |
between:min,max | Value (numeric) or length (string) between min and max inclusive |
nullable combined with requiredBy default, nullable stops the execution of the following rules as soon as it
matches. Exception: if required also appears in the chain, required
runs anyway. This lets you write nullable|required to mean
"must be present even if empty" and keep the semantics users expect.
Type rules​
| Rule | Description |
|---|---|
alpha | Alphabetic characters only |
alphanum | Alphanumeric characters only |
number | The field must be a number |
int | The field must be an integer |
float | The field must be a decimal number |
boolean / bool | Accepts true, false, 0, 1, '0', '1', 'true', 'false' |
json | The field must be a valid JSON string |
uuid | The field must be a canonical UUID (versions 1 to 5) |
A form submission delivers every field as a string, but a JSON body keeps its native types: {"active": false, "age": 7} reaches the validator as a real boolean and a real integer. The rules accept these as such: nullable|boolean validates false as a boolean (it is not treated as absent), min, max and size compare a native number by value and a string by length (numeric strings such as a phone number keep length semantics), and string-only rules like alpha or email simply fail on a non-string value instead of throwing.
Format rules​
| Rule | Description |
|---|---|
date | Date format (YYYY-MM-DD) |
datetime | Datetime format (YYYY-MM-DD HH:MM:SS) |
regex:pattern | The field must match the regex pattern |
lower | Lowercase letters only |
upper | Uppercase letters only |
url | The field must be a well-formed URL (filter_var FILTER_VALIDATE_URL) |
ip | The field must be an IPv4 or IPv6 address |
ip:v4 | The field must be an IPv4 address only |
ip:v6 | The field must be an IPv6 address only |
Database rules​
| Rule | Description |
|---|---|
unique:table,column | The value must be unique in the table |
exists:table,column | The value must exist in the table |
!exists:table,column | The value must not exist in the table |
Custom error messages​
You can customize the error messages by passing an array of messages as the third argument:
$validation = validator($data, [
"name" => "required|min:3",
"email" => "required|email"
], [
"name" => [
"required" => "Le nom est obligatoire",
"min" => "Le nom doit contenir au moins 3 caractères"
],
"email" => [
"required" => "L'email est obligatoire",
"email" => "L'email n'est pas valide"
]
]);
Retrieving errors​
The validator provides several methods for retrieving information about the errors:
// Check whether the validation failed
$validation->fails(); // bool
// Retrieve all error messages
$validation->getMessages(); // array
// Retrieve the last error message
$validation->getLastMessage(); // string
// Retrieve the fields that failed
$validation->getCorruptedFields(); // array
// Retrieve the rules that failed
$validation->getFailsRules(); // array
Validation and exceptions​
You can throw a validation exception with the throwError() method:
$validation = validator($data, $rules);
if ($validation->fails()) {
$validation->throwError(); // Throws ValidationException
}
The exception will contain the error messages and will automatically set the HTTP status code to 400.
Validation in controllers​
Here is a practical example of using the validator in a controller:
class UserController
{
public function store()
{
$validation = validator(request()->all(), [
"name" => "required|min:3|max:50",
"email" => "required|email|unique:users,email",
"password" => "required|min:6"
]);
if ($validation->fails()) {
return response()->json([
"errors" => $validation->getMessages()
], 400);
}
// Create the user
User::create(request()->all());
return response()->json([
"message" => "User created successfully"
]);
}
}
Best practices​
Follow these best practices for effective and secure validation:
- Validate early: Validate data as early as possible in the request lifecycle.
- Clear messages: Use descriptive and understandable error messages.
- Composed rules: Combine multiple rules for robust validation.
- Security: Always use server-side validation, even if you have client-side validation.
Is something missing?
If you run into problems with the documentation or have suggestions to improve the documentation or the project in general, please open an issue for us, or send a tweet mentioning the Twitter account @bowframework or directly on github.