Правила валидации в модели Yii2

    Комментариев нет 517

valid-yii2

Правила валидации, они же Rules, в модели — это набор правил, которым подчиняются данные. Например, в модели User есть поля Email, Login, Password, Name, Status при чем первые три обязательны для заполнения, логин должен состоять только из латиницы, а статус по умолчанию должен принимать значение «1». Все это можно сделать через rules.

Телеграм-канал serblog.ru

Пример правил валидации в Yii2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class User  extends \yii\db\ActiveRecord
{
    public function rules()
    {
      return [
        ['status', 'default', 'value' => 1],
        ['login', 'unique'],
        ['login', 'validateLogin'],
        [['id', 'email', 'name', 'login'], 'required'],
        [['password'], 'required', 'on' => 'register'],
        [['id', 'status'], 'integer'],
        ['email', 'email'],
        ['name', 'string', 'max' => 64],
        ['name', 'trim'],
     ];
    }
}

Иногда правил валидации приходится писать много, что довольно утомительно, но здесь на помощь приходит замечательный gii, который генерирует большую часть рутинного кода. Каждое правило является массивом. Важно следить за порядком следования правил. Указывать ключи у первых двух элементов правила не следует, у последующих требуется. Первый элемент — список полей (можно задавать массивом если под правило попадается несколько полей модели, а можно просто строкой, если поле только одно).

Вторым элементом идет указание валидатора. Здесь может быть имя стандартных валидаторов Yii2 или валидаторов, написанных вами, название функции обратного вызова, выполняющей роль валидатора, или анонимная функция. Следующие элементы идут с ключами. Ключом является аргумент валидатора. Есть как общие для всех валидаторов аргументы, так и уникальные для отдельных. Разберем пример построчно:

['status', 'default', 'value' => 1],
status имя атрибута
default указание на стандартный валидатор DefaultValidator
value аргумент валидатора, устанавливающий дефолтное значение

Важно следить за порядком следования правил. Например, установку значения по умолчанию стоит делать до того, как будет объявление обязательных полей.

['login', 'unique'],

unique — стандартный валидатор UniqueValidator, проверяющий, что в БД еще нет записи с таким значением в поле. Ведь нам нужен уникальный логин.

['login', 'validateLogin'],

Как видно из примера, одно поле может валидироваться несколько раз.
validateLogin — это не стандартный валидатор. В данном случае указывается своя собственная функция. Сначала Yii попробует найти метод с таким названием в классе модели, потом постарается найти простую функцию с этим именем. Чтобы Yii вызвала статический метод другого класса, стоит указать в валидаторе вместо validateLogin массив с двумя элементами — имя класса и имя метода. Например так:

['login', ['Helper', 'validateLogin']],

Более подробно про собственные функции валидации расскажу чуть ниже.

[['id', 'email', 'name', 'login'], 'required'],

required — стандартный валидатор RequiredValidator, указывающий, что поля должны быть заполнены. В дополнительных аргументах не нуждается.

[['password'], 'required', 'on' => 'register'],

Поле password было вынесено в отдельный валидатор required, потому что валидировать его стоит только при регистрации пользователя, но не при изменении его данных.
on — технически является аргументом валидатора, практически — аргументом правила. Это дополнительное условия для правила, указывающее на сценарий, при котором требуется применить валидатор. О сценариях читай ниже.

['name', 'string', 'max' => 64],
string стандартный валидатор StringValidator
max параметр валидатора, означающий, что длина строки не может превышать 64 символа

Собственные функции валидации в Yii2

Если вам не подошел ни один из стандартных валидаторов, то вы можете написать свой. Есть несколько способов:

  • Продвинутый — сделать полноценный класс-валидатор, унаследовав его от класса Validator. Но это слишком сложно и редко имеет смысл.
  • Написать функцию валидации. Этот способ я опишу подробнее
1
2
3
4
5
6
7
public function  validateLogin($attribute)
{
  if(!preg_match('/^[a-zA-Z]{3,16}$/', $this->$attribute))
  {
    $this->addError($attribute, 'Login incorrect');
  }
}

Код прост до безобразия. В данном случае это метод класса модели. Имеем на входе $attribute — название поля. Проверяем значение этого поля. Если значение невалидно — генерируем ошибку.

Стоит обратить внимание, что в данном случае $attribute содержит строку с именем поля, поэтому чтобы получить значение поля, необходимо вызвать такую конструкцию: $this->attribute

Сценарии валидации в Yii2

Часто мы сталкиваемся с тем, что в одном случае нужно применить одни правила, а в другом — другие. Например регистрация, обновление профиля, восстановление пароля — это разные сценарии сохранения модели юзера. Здесь к нам на помощь приходят сценарии. Чтобы указать валидатору, что правило нужно применять только в определенных сценариях, нужно задать правилу параметр «on»:

// так
[['password'], 'required', 'on' => 'register']
 
// или так
[['password'], 'required', 'on' => ['register', 'change_password']]

Кроме того, можно не указывать сценарии для каждого правила. Вместо этого можно описать сценарии в специальном методе модели:

1
2
3
4
5
6
7
8
9
10
11
class User extends \yii\db\ActiveRecord
{
  public function scenarios()
  {
    $scenarios = parent::scenarios();
    $scenarios['login'] = ['login', 'password'];
    $scenarios['register'] = ['login', 'email', 'password'];
    self::SCENARIO_DEFAULT => ['login', '!password']
    return $scenarios;
  }
}

Какой сценарий использовать, указывается при сохранении модели:

// так
$user = new User(['scenario' => 'register']);
 
// или так
$user = new User();
$user->scenario = 'register';
 
// или так
$user = User::findByID($id)->one();
$user->scenario = 'login';

Условная валидация when

Атрибут правила when указывает, в каком случае нужно использовать правило. Чем-то напоминает сценарии, но не требует явного указания сценария. Значением должна быть функция обратного вызова:

// поле "name" обязательно для заполнения, только для юзера с логином "Vasya"
['name', 'required', 'when' => function($model) { return $model->login == 'Vasya'; }],
 
// поле "is_vampire" принимает значение "1", только если юзер регистрируется ночью
['is_vampire', 'default', 'value' => 1, 'when' => function($model) { return date('H') < = 4; }],

Условная валидация на стороне клиента whenClient

Для полного счастья следует так же добавить условие проверки и на сторону клиента. Для этого используется параметр whenClient, в который необходимо передать JS-код проверки.

['name', 'required', 'whenClient' => "function (attribute, value) {return $('#login').value == 'Vasya';}"],

Естественно, условие будет автоматически добавлено только при условии использования функционала Yii для создания форм.

SkipOnEmpty

Указывает валидатору пропускать или не пропускать правило, если значение поля пустое. По умолчанию true (то есть пропускать).

SkipOnError

Указывает валидатору пропускать или не пропускать правило, в предыдущих правилах для этого поля уже была ошибка. По умолчанию true (то есть пропускать).

Любая сумма на развитие сайта

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *