Validation
Validation answers the question whether what a visitor sent may be saved: is the title filled in, does the email look like an email. In CodeIgniter the conditions are written as a string of rules for each field. Rules are written in a controller method, and shared groups go to the file app/Config/Validation.php.
The first check
The controller method validateData() checks any array:
// app/Controllers/Posts.php
public function check(): string
{
$data = ['title' => 'PHP'];
$rules = ['title' => 'required|min_length[5]'];
if ($this->validateData($data, $rules)) {
return 'The data is valid';
}
return implode(', ', $this->validator->getErrors());
}Add the route $routes->get('check', 'Posts::check'); and open /check. The title is shorter than five characters, so the page shows an error message for the title field. Rules are separated with a vertical bar and checked from left to right.
Checking a request
Form data is checked with the validate() method — it takes the data from the request itself:
public function create()
{
$rules = [
'title' => 'required|min_length[5]|max_length[255]',
'body' => 'required',
];
if (! $this->validate($rules)) {
return redirect()->back()->withInput();
}
model(PostModel::class)->insert($this->validator->getValidated());
return redirect()->to('/posts');
}If the data fails the check, the visitor returns to the form, and withInput() keeps the entered values and the errors for the next page. getValidated() returns only the fields that have rules. The form and the error output are covered in the next lesson.
Common rules
| Rule | What it checks |
|---|---|
required | The field is filled in |
min_length[5], max_length[255] | The string length |
valid_email | An email address |
integer, numeric | A number |
greater_than[0], less_than[100] | The bounds of a number |
in_list[draft,published] | One of the values |
matches[password] | Equality with another field |
is_unique[users.email] | The value is not in the table yet |
permit_empty | The field may be empty |
Custom messages
The standard messages contain the raw field name. Your own label and text are set like this:
$rules = [
'title' => [
'label' => 'Title',
'rules' => 'required|min_length[5]',
'errors' => [
'required' => 'Please enter a title.',
'min_length' => 'The title must be at least 5 characters long.',
],
],
];The keys of the errors array are rule names. Now an empty field shows "Please enter a title.".
Rule groups
Rules needed in several places are written once in app/Config/Validation.php as a class property:
// app/Config/Validation.php
public array $post = [
'title' => 'required|min_length[5]|max_length[255]',
'body' => 'required',
];In a controller the group is called by the property name: $this->validate('post').
Rules in the model
Rules can also be written in the model — in the $validationRules property. Then they apply on every insert(), update() and save(); on failure the method returns false, and $model->errors() gives the messages.
Common mistake
Never save $this->request->getPost() as a whole: the request may contain fields that were not in the form. Take the data from $this->validator->getValidated() — it holds only what the rules describe and what passed the check.