Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

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],
    ];
}
ValidatorWhat it requires
requiredThe field is filled in
stringA string, with min and max of a given length
integer, numberAn integer or any number
email, urlAn email or site address
inA value from the range list
uniqueNo such value in the table yet
compareEquality with another field, for example a repeated password
trim, defaultThey 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'].

Thanks for reading!

Donate to the site — we work hard for you.