Yii. Валидация. Сценарии

В момент, когда пользователь отправляет данные формы, а модель их получает, нам необходимоудостовериться, что эти данные корректны, прежде, чем мы будем их использовать. Это осуществляется посредством проверки данных в соответствии с набором правил.

Правила валидации полей модели описываются в rules(). Каждое правило представлено в виде
array(
    'список полей модели',
    'валидатор',
    'on'=>'имя сценария',
    'except'=>'имя сценария',
    'message'=>'сообщение об ошибке',
    …параметры валидации…
);
Думаю, в этой записи все предельно ясно. Мы указываем список полей модели, для которых будет применяться данный валидатор для сценариев, указанных в on, и не будет применяться для сценариев, указанных в except. Возможность исключать отдельные правила появилась, начиная с версии 1.1.11.

Список сценариев в параметрах on и except может быть задан двумя способами: строкой или массивом.
'on'=>array('update', 'insert'),
'except'=>'ignore, this, scenarios, at-all',

Сценарии по умолчанию


При создании модели (new CActiveRecord) устанавливается сценарий insert.
При загрузке модели (все производные от find и последующем сохранении - update CActiveRecord) устанавливается сценарий update.
Правила валидации, в которых не указаны сценарии, срабатывают при любых сценариях.
Чтобы валидация модели проходила по нужному сценарию (если это не сценарий по умолчанию), необходимо установить этот сценарий.
$modelA = User::model()->findByPk(1); // $model->scenario = 'update'
$modelB = new User();                 // $model->scenario = 'insert'
$modelB->scenario = 'light';          // custom scenario
if ($modelB->validate()) {            // will only apply rules of the "light" scenario
}

Откуда берутся валидаторы

Yii ищет валидатор в определённом порядке:
  1. Метод модели с тем же именем, что указано в массиве. Validator может быть именем метода в классе модели данных. В таком случае метод проверки оформляется следующим образом:
    public function ValidatorName($attribute,$params) {
       …
    }
    
  2. Встроенный валидатор Yii, унаследованный от CValidator. Ниже приведен полный список предопределенных псевдонимов валидаторов.
  3. Путь или псевдоним, указывающий на свой валидатор.
    Можно указать Validator в качестве имени класса. В этом случае для проверки данных в момент применения правила создается экземпляр класса проверки. Дополнительные параметры в правиле используются для инициализации значений атрибутов экземпляра. Класс проверки должен быть производным классом от CValidator.

Предопределенные валидаторы Yii


boolean (CBooleanValidator)

проверяет значение атрибута на соответствие либо свойству trueValue, либо свойству falseValue
allowEmptyможет ли значение равняться null или быть пустым
falseValueзначение, представляющее статус false. По умолчанию - '0'
trueValueзначение, представляющее статус true. По умолчанию - '1'
strictявляется ли сравнение строгим: должны совпадать не только значения, но и их тип

captcha (CCaptchaValidator)

проверяет атрибут на соответствие коду верификации, отображенному на изображении капчи. Валидатор должен использоваться с компонентом CCaptchaAction
allowEmptyможет ли значение равняться null или быть пустым
captchaActionидентификатор действия, которое генерирует изображение капчи. По умолчанию - 'captcha', т.е. действие 'captcha', определенное в текущем контроллере. Также это может быть маршрут, содержащий идентификаторы контроллера и действия
caseSensitiveдолжно ли сравнение быть регистрозависимым. По умолчанию - false

compare (CCompareValidator)

сравнивает значение определенного атрибута с другим значением на равенство.
Сравниваемое значение может быть значением другого атрибута (определенного свойством compareAttribute) или постоянным значением (определенным свойством compareValue).
Если определены оба свойства, преимущество имеет второе.
Если не определено ни одно из них, атрибут будет сравнен с другим атрибутом с именем вида "ATTRNAME_repeat", где ATTRNAME - имя исходного атрибута.
Начиная с версии 1.0.8, валидатор поддерживает различные операторы сравнения. Ранее сравнивалось только равенство двух значений
allowEmptyможет ли значение равняться null или быть пустым
compareAttributeимя атрибута, с которым сравнивается исходный атрибут
compareValueпостоянное значение, с которым сравнивается атрибут
operatorоператор сравнения. По умолчанию - '='. Допустимы следующие операторы:
  • '=' или '==': равенство двух значений. Если свойство strict установлено в true, сравнение будет строгим (т.е. тип значения также будет проверен).
  • '!=': проверка того, что два значения не равны. Если свойство strict установлено в true, сравнение будет строгим (т.е. тип значения также будет проверен).
  • '>': валидируемое значение больше значения, с которым происходит сравнение.
  • '>=': валидируемое значение больше или равно значения, с которым происходит сравнение.
  • '<': валидируемое значение меньше значения, с которым происходит сравнение.
  • '<=': валидируемое значение меньше или равно значения, с которым происходит сравнение.
strictявляется ли сравнение строгим: должны совпадать не только значения, но и их тип

date (CDateValidator)

проверяет соответствие атрибута дате, времени или временной отметке. Установкой свойства format можно определять формат значения даты. Если переданное значение даты не соответствует данному формату, атрибут считается неверным
allowEmptyможет ли значение равняться null или быть пустым
formatшаблон формата, которому должно соответствовать значение даты. Может быть строкой или массивом, представляющим несколько форматов. По умолчанию - 'MM/dd/yyyy'. Остальные форматы описаны в API CDateTimeParser
timestampAttributeимя атрибута для получения результата разбора. Если даное свойство не равно null и валидация прошла успешно, атрибут будет заполнен значением результата разбора в виде временной отметки

default (CDefaultValueValidator)

присваивает атрибутам определенные значения. Он не проводит валидацию. В основном, он позволяет динамически определить в атрибуте значение по умолчанию.
setOnEmptyдолжно ли значение по умолчанию устанавливаться только при нулевом или пустом значении атрибута. По умолчанию - true. Если установлено в false, атрибут всегда будет связываться со значением по умолчанию, даже если он уже имеет явно присвоенное значение
valueзначения по умолчанию, в которые должны быть установлены атрибуты

email (CEmailValidator)

проверяет, что значение атрибута - правильный адрес email
allowEmptyможет ли значение равняться null или быть пустым
allowNameдопустимо ли имя в адресе email (например, "Qiang Xue "). По умолчанию - false
checkMXпроверять ли запись MX
checkPortпроверять ли 25-й порт
fullPatternрегулярное выражение, используемое для проверки адреса с именем. Свойство используется только если свойство allowName установлено в true
patternрегулярное выражение, используемое для проверки адреса без имени

exist (CExistValidator)

проверяет наличие значения атрибута в таблице базы данных. Данный валидатор часто используется для проверки того, что внешний ключ содержит значение, которое может быть найдено во внешней таблице.
allowEmptyможет ли значение равняться null или быть пустым
attributeNameимя атрибута ActiveRecord-класса, используемое для поиска значения валидируемого атрибута. По умолчанию - null, т.е. использование имени валидируемого атрибута
caseSensitiveиспользовать ли регистрозависимую проверку
classNameимя ActiveRecord-класса, используемое для поиска валидируемого атрибута. По умолчанию - null, т.е. использование ActiveRecord-класса валидируемого атрибута. Вы можете использовать здесь псевдонимы (и пути) для ссылки на имя класса
criteriaдополнительный критерий запроса. Будет объединен с условием, проверяющим существование значения атрибута в соответствующем столбце таблицы. Данный массив будет использован для создания экземпляра CDbCriteria

file (CFileValidator)

проверяет правильность полученного файла.
Использует класс модели и имя атрибута для получения информации о загруженном файле.
Проверяет успешность загрузки файла, соответствие размера файла и его тип.
Валидатор будет пытаться извлечь переданные данные, если атрибут не был установлен ранее.
Запомните, что это невозможно при массовом вводе данных:
foreach($models as $i=>$model)
    $model->attribute = CUploadedFile::getInstance($model, "[$i]attribute");
Запомните, что вы должны использовать метод {@link CUploadedFile::getInstances} для загрузки нескольких файлов.
При использовании CFileValidator с active record-объектами часто используется следующий код:
 if($model->save()) {
    // одиночная загрузка
    $model->attribute->saveAs($path);
    // множественная загрузка
    foreach($model->attribute as $file)
       $file->saveAs($path);
 }
Вы можете использовать CFileValidator для проверки атрибутов файла.
allowEmptyможет ли значение равняться null или быть пустым
maxFilesмаксимальное количество файлов
maxSizeмаксимальный размер в байтах/ По умолчанию - null, т.е. без ограничения.
Примечание: максимальный размер также устанавливается свойством 'upload_max_filesize' в файле INI и скрытым полем 'MAX_FILE_SIZE'
mimeTypesсписок MIME-типов, разрешенных к загрузке
minSizeминимальный размер в байтах
tooLargeсообщение об ошибке, выдаваемое если файл слишком большой
tooManyсообщение, выдаваемое если загружено слишком много файлов
tooSmallсообщение, выдаваемое если загруженный файл слишком мал
typesсписок расширений, допустимых для загрузки. Он может быть массивом или строкой, содержащей расширения, разделенные пробелом или запятой (например, "gif, jpg"). Расширения регистронезависимы. По умолчанию - null, т.е. допустимы любые расширения
wrongMimeTypeсообщение, выдаваемое если файла с данным MIME-типом загружать нельзя
wrongTypeсообщение, выдаваемое если данный тип файла загружать нельзя

filter (CFilterValidator)

преобразовывает валидируемые данные, используя фильтр.
CFilterValidator на самом деле не валидатор, а процессор данных. Он выполняет определенный метод фильтрации над атрибутом и возвращает результат обратно в атрибут. Метод фильтрации должен иметь следующую структуру:
function foo($value) {...return $newValue; }
Многие функции PHP имеют такую структуру (например, trim). Для определения метода фильтрации присвойте свойству filter имя функции.
filterметод-фильтр

in (CRangeValidator)

проверяет, чтобы значение атрибута было в списке, определенном свойством range.Вы можете инвертировать логику валидации при помощи свойства not
allowEmptyможет ли значение равняться null или быть пустым
rangeсписок допустимых значений, среди которых должен быть атрибут
strictявляется ли сравнение строгим: должны совпадать не только значения, но и их тип
notинвертировать ли логику валидации. По умолчанию - false. Если установлено в значение true, то значение атрибут не должно находиться в списке значений, определенных свойством range

length (CStringValidator)

проверяет соответствие длины строкового атрибута некоторой величине. Валидатор должен использоваться только для строковых атрибутов
allowEmptyможет ли значение равняться null или быть пустым
encodingкодировка строки валидируемого значения (например, 'UTF-8').
Установка данного свойства требует включенного PHP расширения mbstring.
Значение данного свойства будет использовано в качестве второго параметра функции mb_strlen(). По умолчанию равно кодировке приложения, т.е., для вычисления длины строки будет использоваться кодировка приложения если доступна функция mb_strlen(), иначе используется функция strlen()
isточное количество символов
maxмаксимальное количество символов
minминимальное количество символов
tooShortсообщение об ошибке, выдаваемое если количество символов слишком мало
tooLongсообщение об ошибке, выдаваемое если количество символов слишком велико

match (CRegularExpressionValidator)

проверяет атрибут на соответствие определенному pattern регулярному выражению. Вы можете инвертировать логику валидации при помощи свойства not (доступно с версии 1.1.5)
allowEmptyможет ли значение равняться null или быть пустым
notинвертировать ли логику проверки. По умолчанию - false. Если установлено в значение true, то регулярное выражение, определенное свойством pattern не должно соответствовать проверяемому значению атрибута
patternрегулярное выражение

numerical (CNumberValidator)

проверяет, что значение атрибута является числом
allowEmptyможет ли значение равняться null или быть пустым
integerOnlyтолько целые числа
integerPatternрегулярное выражение для поиска целых чисел
maxмаксимальное значение
minминимальное значение
numberPatternрегулярное выражение для поиска чисел
tooBigсообщение об ошибке, выдаваемое если значение слишком велико
tooSmallсообщение об ошибке, выдаваемое если значение слишком мало

required (CRequiredValidator)

проверяет, не является ли значение атрибута пустым
requiredValueжелаемое значение, котороое должен иметь атрибут.
Если установлено в null, валидатор будет проверять, что значение определенного атрибута не нулевое и не пустое.
Если установлено в некоторое ненулевое значение, валидатор будет проверять значение атрибута на соответствие значению этого свойства. По умолчанию - null
strictявляется ли сравнение строгим: должны совпадать не только значения, но и их тип

safe(CSafeValidator)

помечает атрибут безопасным для массового присваивания

type (CTypeValidator)

проверяет соответствие типа атрибута типу, определенному свойством type. Поддерживаются следующие типы данных:
  • integer 32-х битные целочисленные знаковые данные.
  • float Числа с плавающей точкой двойной точности.
  • string Строковые данные.
  • array Массив.
  • date Дата.
  • time Время (доступен с версии 1.0.5).
  • datetime Дата и время (доступен с версии 1.0.5).
Для типа date свойство dateFormat будет использоваться для определения того, как разбирать строку даты. Если переданное значение даты не соответствует данному формату, атрибут будет считаться неправильным.
Начиная с версии 1.1.7 существует отдельный валидатор дат CDateValidator. Используйте его для валидации значений дат.
allowEmptyможет ли значение равняться null или быть пустым
dateFormatформат для валидации дат
datetimeFormatформат для валидации даты и времени
timeFormatформат для валидации времени
typeтип данных

unique (CUniqueValidator)

проверяет значение атрибута на уникальность в соответствующей таблице БД
allowEmptyможет ли значение равняться null или быть пустым
attributeNameимя атрибута класса ActiveRecord, используемое для проверки значения
caseSensitiveявляется ли сравнение регистронезависимым
classNameимя класса ActiveRecord, используемого для проверки
criteriaдополнительный критерий запроса
messageпользовательское сообщение об ошибке. Можно использовать маркеры "{attribute}" и "{value}", которые будут заменены реальным именем или значением атрибута соответственно
skipOnErrorпропускать ли правило в случае, если для указанного атрибута ошибка уже произошла

unsafe(CUnsafeValidator)

помечает связанные атрибуты как небезопасные так, что они не могут быть присвоены пакетно

url (CUrlValidator)

проверяет, чтобы атрибут был допустимым URL-адресом протоколов http и https
allowEmptyможет ли значение равняться null или быть пустым
defaultSchemeURI-схема по умолчанию. Если входное значение не содержит части со схемой, то схема по умолчанию будет подставлена перед значением (изменив тем самым входное значение).
По умолчанию - null, т.е., URL-адрес должен содержать часть со схемой
patternрегулярное выражение, используемое при валидации. С версии 1.1.7 шаблон может содержать метку {schemes}, заменяемую регулярным выражением, представленным свойством validSchemes
validSchemesсписок URI-схем, которые должны считаться валидными. По умолчанию, схемы http и https считаются валидными

Примеры

// имя пользователя — обязательное поле формы
array('username', 'required'),
// длина имени пользователя должна быть от 3 до 12 символов включительно
array('username', 'length', 'min'=>3, 'max'=>12),
// в сценарии регистрации значения полей «password» и «password2» должны быть равны
array('password', 'compare', 'compareAttribute'=>'password2', 'on'=>'register'),
// в сценарии аутентификации поле `password` должно быть проверено на соответствие указанному имени пользователя
array('password', 'authenticate', 'on'=>'login'),
Еще немного о валидации здесь.

Комментарии

  1. в теме не хватает примера собственного валидатора

    ОтветитьУдалить
  2. Спасибо. Гуглил значение по-умолчанию.
    Описание на русском языке в 4 часа ночи почему-то звучит доходчивее, нежели на английском в документации. =)

    ОтветитьУдалить
  3. Понятное объяснение.

    ОтветитьУдалить
  4. Здорово, узнал много полезного!

    ОтветитьУдалить

Отправить комментарий

Популярные сообщения