2 · курс
0%
Главная/📝Формы и валидация

29Встроенные валидаторы

Справочник валидаторов ядра — required, string, integer/number, email, url, ip, date, compare, in, match, boolean, default, filter, trim, each, exist, unique, file, image, captcha, safe — с ключевыми опциями и типичными примерами.

⏱ ~7 мин 📚 1 глава руководства

Каждый валидатор — класс в yii\validators, но в rules() его зовут коротким именем. Ниже — все встроенные, сгруппированные по назначению, с опциями, которые реально нужны. Общие для всех: message, on, except, skipOnEmpty, skipOnError, when, whenClient, enableClientValidation.

Обязательность и умолчания#

required
не пусто. requiredValue (ожидать конкретное значение), strict (сравнивать строго). Один из двух проверяющих валидаторов (второй — captcha), который срабатывает и на пустом значении; у default, filter и trim skipOnEmpty тоже выключен, но они не проверяют, а меняют значение
default
подставить value (значение или замыкание), если атрибут пуст. Не проверяет, а заполняет
safe
«ничего не проверять, но считать атрибут безопасным» для массового присваивания
PHP
[['username', 'password'], 'required'],
['accept', 'required', 'requiredValue' => 1, 'message' => 'Примите условия'],
['age', 'default', 'value' => null],
['country', 'default', 'value' => 'USA'],
['from', 'default', 'value' => function ($model) { return date('Y-m-d'); }],
['notes', 'safe'],

Строки и форматы#

string
строка длиной min..max или ровно length; encoding (по умолчанию charset приложения)
email
адрес; allowName (разрешить Иван <ivan@site.ru>), checkDNS (проверить MX-запись), enableIDN
url
URL; validSchemes (['http', 'https']), defaultScheme (дописать, если схемы нет), enableIDN
ip
IPv4/IPv6; ipv4, ipv6, subnet (true — обязательно с маской, null — можно с маской), normalize, ranges (белый/чёрный список: ['10.0.1.0/24', '!10.0.0.0/8', 'any']), negation (разрешить !)
match
регулярное выражение pattern; not — инвертировать
trim
обрезать пробелы (фильтр); chars — какие символы
filter
применить callback filter (строка, замыкание, [класс, метод]); skipOnArray — не применять к массивам
PHP
['username', 'string', 'length' => [4, 24]],
['email', 'email', 'checkDNS' => true],
['website', 'url', 'defaultScheme' => 'https'],
['ip', 'ip', 'ipv6' => false, 'ranges' => ['10.0.0.0/8', '!any']],
['username', 'match', 'pattern' => '/^[a-z]\w*$/i'],
['username', 'match', 'pattern' => '/^admin$/', 'not' => true, 'message' => 'Имя занято'],
[['title', 'body'], 'trim'],
['username', 'filter', 'filter' => 'strtolower'],
['phone', 'filter', 'filter' => function ($value) { return preg_replace('/\D/', '', $value); }],

ip при subnet => null и normalize => true приведёт 192.168.1.1 к 192.168.1.1/32; при expandIPv6 — развернёт сокращённую запись.

Числа и логика#

integer
целое; min, max, tooSmall, tooBig
number (double)
любое число; те же min/max; integerPattern, numberPattern
boolean
trueValue/falseValue (по умолчанию 1/0), strict. Не преобразует значение
compare
сравнить с другим атрибутом compareAttribute или значением compareValue; operator (==, ===, !=, !==, >, >=, <, <=); type — как сравнивать: string (по умолчанию: оба значения приводятся к строке и сравниваются операторами PHP) или number (приводятся к float)
in
значение из range; strict, not, allowArray (проверить каждый элемент массива)
PHP
['age', 'integer', 'min' => 18],
['price', 'number', 'min' => 0, 'max' => 1e6],
['salary', 'double'],
['remember_me', 'boolean'],
['is_active', 'boolean', 'trueValue' => true, 'falseValue' => false, 'strict' => true],
['password_repeat', 'compare', 'compareAttribute' => 'password'],
['age', 'compare', 'compareValue' => 30, 'operator' => '>=', 'type' => 'number'],
['level', 'in', 'range' => [1, 2, 3]],
['tags', 'in', 'range' => ['php', 'yii'], 'allowArray' => true],

Даты#

date
дата в формате format (ICU: yyyy-MM-dd, или php:Y-m-d); timestampAttribute — куда записать UNIX-время; timestampAttributeFormat — или в каком формате записать; min/max (+tooSmall/tooBig); timeZone, locale
datetime, time
тот же валидатор с type => 'datetime' / 'time' (короткие имена — с 2.0.10)
PHP
[['from_date', 'to_date'], 'date'],
['birthday', 'date', 'format' => 'php:d.m.Y', 'timestampAttribute' => 'birthday_ts'],
['created', 'datetime', 'format' => 'php:Y-m-d H:i:s',
    'timestampAttribute' => 'created', 'timestampAttributeFormat' => 'php:Y-m-d H:i:s'],
['start', 'date', 'min' => date('Y-m-d'), 'tooSmall' => 'Дата уже прошла'],

Без format берётся dateFormat компонента formatter. С timestampAttribute проверенное значение преобразуется в UNIX-timestamp и записывается в атрибут (можно в тот же самый) — удобно для сохранения в INT.

Массивы и вложенность#

each
применить rule к каждому элементу массива; allowMessageFromRule (сообщение от вложенного правила), stopOnFirstError
PHP
['categoryIDs', 'each', 'rule' => ['integer']],
['emails', 'each', 'rule' => ['email'], 'allowMessageFromRule' => false, 'message' => 'Один из адресов неверен'],

Проверяет только один уровень; для сложных структур — свой валидатор. Не работает с unique/exist через targetAttribute.

Проверки по базе данных#

exist
значение существует в таблице: targetClass (по умолчанию — класс модели), targetAttribute (столбец или карта ['a1' => 'b1']), filter (доп. условие), allowArray, targetRelation (по связи AR, 2.0.14)
unique
значение уникально в таблице; те же опции, comboNotUnique (сообщение для составного ключа). Для AR исключает саму запись при обновлении
PHP
['a1', 'exist'],                                                  // столбец a1 в таблице модели
['category_id', 'exist', 'targetClass' => Category::class, 'targetAttribute' => 'id'],
// пара (a1, a2) должна существовать; ошибка — только у a1
['a1', 'exist', 'targetAttribute' => ['a1', 'a2']],
// значение a2 ищется в столбце a1: [атрибут модели => столбец таблицы]
['a1', 'exist', 'targetAttribute' => ['a2' => 'a1']],
['a1', 'exist', 'filter' => ['status' => 1]],
['user_id', 'exist', 'targetRelation' => 'user'],

['username', 'unique'],
['email', 'unique', 'targetClass' => User::class, 'filter' => ['status' => User::STATUS_ACTIVE]],
[['slug', 'lang'], 'unique', 'targetAttribute' => ['slug', 'lang']],   // комбинация уникальна

Оба не имеют клиентской реализации — используйте AJAX-валидацию.

Файлы и изображения#

file
UploadedFile: extensions, mimeTypes (image/*, text/plain), minSize, maxSize, maxFiles (0 — без ограничения), checkExtensionByMimeType (сверять расширение с реальным MIME, по умолчанию true), wrongExtension, tooBig, tooMany…
image
file + проверка изображения: minWidth, maxWidth, minHeight, maxHeight, notImage, underWidth, overWidth…
PHP
['file', 'file', 'extensions' => ['pdf', 'docx'], 'maxSize' => 5 * 1024 * 1024, 'skipOnEmpty' => false],
['avatar', 'image', 'extensions' => 'png, jpg', 'minWidth' => 100, 'maxWidth' => 1000, 'minHeight' => 100],
['docs', 'file', 'maxFiles' => 10],

Помните про upload_max_filesize/post_max_size в php.ini и enctype="multipart/form-data" — подробнее в разделе Формы.

CAPTCHA#

captcha
сверяет ввод с виджетом yii\captcha\Captcha; captchaAction (по умолчанию site/captcha), caseSensitive. Как и required, работает с пустым значением — пустое поле сразу даёт ошибку
PHP
// модель
['verifyCode', 'captcha'],
// контроллер: действие captcha в actions()
'captcha' => ['class' => 'yii\captcha\CaptchaAction', 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null],
// форма
<?= $form->field($model, 'verifyCode')->widget(Captcha::class) ?>

Требует расширения GD или ImageMagick с поддержкой FreeType.

Сводка по ключевым опциям#

Валидатор Самое важное
requiredrequiredValue, strict
stringmin, max, length
integer, numbermin, max
email, urlcheckDNS / defaultScheme, enableIDN
comparecompareAttribute, operator, type
inrange, not, allowArray
dateformat, timestampAttribute, min, max
eachrule
exist, uniquetargetClass, targetAttribute, filter
file, imageextensions, maxSize, maxFiles, minWidth…
matchpattern, not
filter, trim, defaultfilter / chars / value — меняют значение
Проверь себя5

required и captcha; остальные проверяющие пропускают пустые атрибуты, пока не указан 'skipOnEmpty' => false. У default, filter и trim он тоже выключен, но они не проверяют, а меняют значение.

Записывает в указанный атрибут UNIX-время (или строку в timestampAttributeFormat), полученное из проверенной даты.

Когда значения — не просто числа. Сравнение по умолчанию строковое, и '2024-1-5' > '2024-01-10' оказывается истиной. Для чисел задайте 'type' => 'number', для дат сравнивайте UNIX-время из timestampAttribute.

['ids', 'each', 'rule' => ['integer']].

Правилом ['attr', 'safe'].