Models and validation rules
Visitor data cannot be trusted: a title may be empty and an email mistyped. In Yii the requirements for data are described in the model, in the rules() method. Validation is run with one call and collects the error messages itself.
Where rules are described
Rules are written in the model class. Add the method to models/Post.php:
// models/Post.php
public function rules(): array
{
return [
[['title', 'body'], 'required'],
];
}Every rule is an array: the fields first, then the validator name. Here the title and the body are required.
Running validation
$post = new Post();
$post->title = '';
if (!$post->validate()) {
print_r($post->errors);
}The code prints an array with two messages: "Title cannot be blank" and "Body cannot be blank". The save() method calls validate() itself, so a post with an empty title does not get into the database.
Built-in validators
public function rules(): array
{
return [
[['title', 'body'], 'required'],
['title', 'string', 'min' => 3, 'max' => 255],
['status', 'in', 'range' => [0, 1]],
['slug', 'unique'],
['title', 'trim'],
['status', 'default', 'value' => 0],
];
}| Validator | What it requires |
|---|---|
required | The field is filled in |
string | A string, with min and max of a given length |
integer, number | An integer or any number |
email, url | An email or site address |
in | A value from the range list |
unique | No such value in the table yet |
compare | Equality with another field, for example a repeated password |
trim, default | They do not check but fix: strip spaces, set a default value |
Your own error text
['title', 'required', 'message' => 'Enter the post title.'],The message parameter replaces the standard message.
Field labels
Messages use the field name. It is set by the attributeLabels() method:
// models/Post.php
public function attributeLabels(): array
{
return [
'title' => 'Headline',
'body' => 'Text',
];
}Now the error reads "Headline cannot be blank". The same labels appear in forms and tables.
Your own rule
If the built-in validators are not enough, a model method serves as the rule name:
public function rules(): array
{
return [
['title', 'validateNoCaps'],
];
}
public function validateNoCaps(string $attribute): void
{
if (mb_strtoupper($this->$attribute) === $this->$attribute) {
$this->addError($attribute, 'Do not write the title in capital letters only.');
}
}The method receives the field name and, on violation, adds an error with addError().
A model without a table
Data that is not stored in a table (a login form, a contact form) is described by a class that extends yii\base\Model. Fields are declared in it as public properties, and rules() is written the same way. The project has an example: models/ContactForm.php.
Common mistake
The load() method, which fills a model with form data, copies only the fields mentioned in rules(). A field without a single rule is considered unsafe and silently skipped, so the form value is not saved. If a field needs no validation, give it the safe rule: ['slug', 'safe'].