
Если вы спрашиваете: «Что такое Yii?» Посмотрите мой предыдущий учебник: Введение в Yii Framework , который рассматривает преимущества Yii и включает обзор того, что нового в Yii 2.0, выпущенном в октябре 2014 года.
В этой серии «Программирование с Yii2» я расскажу читателям, как использовать обновленную версию Yii2 Framework для PHP. Этот урок — наша вторая часть, посвященная валидаторам Yii2 . Валидаторы упрощают код, необходимый для проверки ввода, т. Е. Проверки соответствия или несоответствия ввода данных, как правило, от пользователей через веб-формы. В частности, мы собираемся изучить некоторые из встроенных специальных проверок, которые являются общими для веб-разработки.
Вот список встроенных валидаторов Yii и ссылки на документацию, которую мы собираемся изучить:
- CaptchaValidator : проверяет поле проверки формы CAPTCHA.
- CompareValidator : сравнивает два значения из формы или константы, например, x должно быть меньше 99.
- EmailValidator : Гарантирует, что значение является действительным адресом электронной почты.
- ExistValidator : Гарантирует, что значение существует в другой таблице.
- FileValidator : обеспечивает существование загруженного файла.
- ImageValidator : проверяет изображение и свойства изображения.
- RangeValidator : Гарантирует, что значение находится в списке значений.
- RegularExpressionValidator : выполняет проверку по условию, определенному регулярным выражением.
- UniqueValidator : Гарантирует, что значение уникально в таблице, такой как адрес электронной почты.
- UrlValidator : обеспечивает значение в формате URL, например, http://yourdomain.com.
Я собираюсь показать вам примеры каждой из этих проверок, используя базу кода приложения Hello из предыдущих уроков и пару из нашей серии «Построение стартапа», в которой также используется Yii2. Используйте ссылки GitHub на этой странице, чтобы получить код.
Просто напоминание, я участвую в комментариях ниже. Мне особенно интересно, если у вас есть дополнительные идеи или вы хотите предложить темы для будущих уроков. Вы также можете связаться со мной по адресу @reifman в Твиттере или написать мне на Lookahead Consulting .
Что такое валидатор?
Если вы веб-разработчик, вы, вероятно, знаете, что пользовательскому вводу нельзя доверять. Например, пользователи могут использовать методы SQL-инъекции , чтобы попытаться выполнить запросы, которые изменяют или предоставляют пароли. Кто-то однажды применил SQL-инъекцию к моей установке с открытым исходным кодом PHPList и сумел обнаружить один из моих паролей (PHPList сохранил их в виде простого текста). Чаще всего вы просто хотите, чтобы данные, предоставляемые пользователями, соответствовали типам, формам и диапазонам вашего приложения.
Создание валидаторов в PHP вручную требует времени. Yii Framework предоставляет множество базовых функций проверки, поэтому нет необходимости создавать их с нуля. Но если вам нужны пользовательские расширения, это тоже просто.
Валидации — это еще одна причина, почему я думаю, что всегда имеет смысл создавать приложения на веб-инфраструктуре, такой как Yii, а не на ванильном PHP.
В предыдущих эпизодах мы также много говорили о генераторе кода Yii, Gii. Одним из преимуществ Gii является то, что он напишет соответствующие правила проверки для ваших моделей на основе определений типов SQL в схеме. Это экономит время.
Возможно, вы захотите вернуться к нашему последнему эпизоду, чтобы узнать больше об основных проверках типов в Yii2 .
Теперь давайте начнем с рассмотрения следующего набора встроенных валидаторов Yii2.
Следующий набор валидаторов
Captcha Validator
Начнем с CaptchaValidator, который проверяет, есть ли правильный ответ на поле проверки CAPTCHA . CAPTCHA помогают гарантировать, что человек заполняет форму, надеясь, что автоматизированные сценарии не будут отправлять ее.
Вот пример Yii Captcha в действии:

В нашей кодовой базе Hello я упростил наш пример формы, чтобы на данный момент просто включить поля Thought и Captcha. Вот посмотрите на определения правил кода модели:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
class Sample extends \yii\db\ActiveRecord
{
public $captcha;
/**
* @inheritdoc
*/
public function rules()
{
return [
[[‘thought’], ‘string’, ‘max’ => 255],
[[‘thought’], ‘trim’],
[[‘thought’], ‘required’],
[[‘captcha’], ‘captcha’],
];
}
|
Капча не является частью нашей схемы базы данных — она используется только для проверки формы. Поэтому я добавил в модель атрибут, например public $captcha; ,
Вот код представления формы. Мы должны включить библиотеку Captcha вверху.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\captcha\Captcha;
/* @var $this yii\web\View */
/* @var $model app\models\Sample */
/* @var $form yii\widgets\ActiveForm */
?>
<div class=»sample-form»>
<?php $form = ActiveForm::begin();
<?= $form->errorSummary($model);
<?= $form->field($model, ‘thought’)->textInput([‘maxlength’ => 255]) ?>
<?= $form->field($model, ‘captcha’)->widget(\yii\captcha\Captcha::classname(), [
// configure additional widget properties here
]) ?>
<div class=»form-group»>
<?= Html::submitButton($model->isNewRecord ? ‘Create’ : ‘Update’, [‘class’ => $model->isNewRecord ? ‘btn btn-success’ : ‘btn btn-primary’]) ?>
</div>
<?php ActiveForm::end();
</div>
|
Вот как выглядит проверка Captcha в действии:

Если вы нажмете на капчу, Yii создаст новое изображение.
Валидатор сравнения
Теперь давайте перейдем к CompareValidator . Этот валидатор сравнивает два значения из формы или одно значение формы с константой, например, x должно быть меньше 99.
В этом примере я хочу убедиться, что пользовательский ввод для ранга больше нуля, но меньше или равен 100.
Сначала я добавлю поле ввода обратно в нашу форму для атрибута ранга:
|
01
02
03
04
05
06
07
08
09
10
|
<?php $form = ActiveForm::begin();
<?= $form->errorSummary($model);
<?= $form->field($model, ‘thought’)->textInput([‘maxlength’ => 255]) ?>
<?= $form->field($model, ‘rank’)->textInput() ?>
<?= $form->field($model, ‘captcha’)->widget(\yii\captcha\Captcha::classname(), [
// configure additional widget properties here
]) ?>
|
Затем я добавлю два правила проверки сравнения в нашу модель:
|
01
02
03
04
05
06
07
08
09
10
11
12
|
public function rules()
{
return [
[[‘thought’], ‘string’, ‘max’ => 255],
[[‘thought’], ‘trim’],
[[‘thought’], ‘required’],
[[‘captcha’], ‘captcha’],
[[‘rank’], ‘integer’],
[‘rank’, ‘compare’, ‘compareValue’ => 0, ‘operator’ => ‘>’],
[‘rank’, ‘compare’, ‘compareValue’ => 100, ‘operator’ => ‘<=’],
];
}
|
Вы можете увидеть полный список доступных операторов сравнения здесь .
Вот как выглядит наша форма, когда пользователь отправляет неверный атрибут:

Если мы хотим предоставить конкретные правила ограничения в одном сообщении об ошибке, Yii Validators позволяют вам настроить отображаемую пользователю ошибку, например:

Реализация этого довольно проста с добавлением атрибута сообщения:
|
01
02
03
04
05
06
07
08
09
10
11
12
|
public function rules()
{
return [
[[‘thought’], ‘string’, ‘max’ => 255],
[[‘thought’], ‘trim’],
[[‘thought’], ‘required’],
[[‘captcha’], ‘captcha’],
[[‘rank’], ‘integer’],
[‘rank’, ‘compare’, ‘compareValue’ => 0, ‘operator’ => ‘>’,’message’=>Yii::t(‘app’,’Rank must be between 0 and 100 inclusive.’)],
[‘rank’, ‘compare’, ‘compareValue’ => 100, ‘operator’ => ‘<=’,’message’=>Yii::t(‘app’,’Rank must be between 0 and 100 inclusive.’)],
];
}
|
Обновление нашей схемы для проверки дополнительных проверок
Для некоторых из этих следующих проверочных тестов я попрошу вас добавить несколько полей в базу данных.
В \migrations\m150219_235923_create_sample_table.php мы добавим несколько новых полей для проверки следующего набора валидаторов: электронная почта, URL, имя файла и т. Д.
|
01
02
03
04
05
06
07
08
09
10
11
12
|
$this->createTable(‘{{%sample}}’, [
‘id’ => Schema::TYPE_PK,
‘thought’ => Schema::TYPE_STRING.’
‘goodness’ => Schema::TYPE_SMALLINT .
‘rank’ => Schema::TYPE_INTEGER .
‘censorship’ => Schema::TYPE_STRING .
‘occurred’ => Schema::TYPE_DATE .
’email’ => Schema::TYPE_STRING .
‘url’ => Schema::TYPE_STRING .
‘filename’ => Schema::TYPE_STRING.’
‘avatar’ => Schema::TYPE_STRING.’
], $tableOptions);
|
Затем запустите миграцию вниз, чтобы удалить таблицу, а затем вверх:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
Admins-MBP:hello Jeff$ ./yii migrate/down 1
Yii Migration Tool (based on Yii v2.0.2)
Total 1 migration to be reverted:
m150219_235923_create_sample_table
Revert the above migration?
*** reverting m150219_235923_create_sample_table
> drop table {{%sample}} … done (time: 0.002s)
*** reverted m150219_235923_create_sample_table (time: 0.005s)
Migrated down successfully.
Admins-MBP:hello Jeff$ ./yii migrate/up 1
Yii Migration Tool (based on Yii v2.0.2)
Total 1 new migration to be applied:
m150219_235923_create_sample_table
Apply the above migration?
*** applying m150219_235923_create_sample_table
> create table {{%sample}} … done (time: 0.007s)
*** applied m150219_235923_create_sample_table (time: 0.010s)
Migrated up successfully.
|
Теперь мы готовы проверить валидаторы электронной почты и URL.
Email & URL Validators
EmailValidator гарантирует, что значение является действительным адресом электронной почты, а UrlValidator обеспечивает значение в формате URL, например, http://yourdomain.com.
Создать правила для наших новых полей электронной почты и URL довольно просто:
|
1
2
3
4
5
6
|
public function rules()
{
return [
[[‘thought’], ‘string’, ‘max’ => 255],
[[’email’], ’email’],
[[‘url’], ‘url’],
|
Вот код представления формы. Обратите внимание, как я использую пользовательские метки для улучшения удобства использования формы:
|
01
02
03
04
05
06
07
08
09
10
|
<div class=»sample-form»>
<?php $form = ActiveForm::begin();
<?= $form->errorSummary($model);
<?= $form->field($model, ‘thought’)->textInput([‘maxlength’ => 255]) ?>
<?= $form->field($model, ’email’)->textInput()->label(Yii::t(‘app’,’Your email address’)) ?>
<?= $form->field($model, ‘url’)->textInput()->label(Yii::t(‘app’,’Your website’)) ?>
|
Вот валидаторы в действии:

Это, безусловно, очень полезно для веб-приложений.
Exist Validator
ExistValidator очень полезен в определенных сценариях. Это может гарантировать, что значение существует в другой таблице. И его можно использовать различными способами — вот несколько примеров, приведенных в документации:
|
01
02
03
04
05
06
07
08
09
10
|
// a1 needs to exist
[‘a1’, ‘exist’]
// a1 needs to exist, but its value will use a2 to check for the existence
[‘a1’, ‘exist’, ‘targetAttribute’ => ‘a2’]
// a1 and a2 need to exist together, and they both will receive error message
[[‘a1’, ‘a2’], ‘exist’, ‘targetAttribute’ => [‘a1’, ‘a2’]]
// a1 and a2 need to exist together, only a1 will receive error message
[‘a1’, ‘exist’, ‘targetAttribute’ => [‘a1’, ‘a2’]]
// a1 needs to exist by checking the existence of both a2 and a3 (using a1 value)
[‘a1’, ‘exist’, ‘targetAttribute’ => [‘a2’, ‘a1’ => ‘a3’]]
|
В документации Yii подчеркивается, что Exist можно использовать для «проверки того, что внешний ключ содержит значение, которое можно найти во внешней таблице».
Для нашего примера я собираюсь создать правило, которое проверяет, что адрес электронной почты в форме уже существует в нашей зарегистрированной таблице User. Чтобы сделать это, мы используем targetClass, который сообщает Yii, какой класс (или таблица моделей) искать адрес электронной почты пользователя для проверки.
Вот определение правила — обратите внимание на включение нашей модели User вверху:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<?php
namespace app\models;
use Yii;
use yii\models\User;
/**
* This is the model class for table «sample».
*
* @property integer $id
* @property string $thought
* @property integer $goodness
* @property integer $rank
* @property string $censorship
* @property string $occurred
*/
class Sample extends \yii\db\ActiveRecord
{
public $captcha;
/**
* @inheritdoc
*/
public function rules()
{
return [
[[‘thought’], ‘string’, ‘max’ => 255],
[[’email’], ’email’],
[[’email’], ‘exist’,’targetClass’=>’\app\models\User’,’message’=>Yii::t(‘app’,’Sorry, that person hasn\’t registered yet’)],
[[‘url’], ‘url’],
|
Это указывает Yii запросить таблицу User, чтобы убедиться, что указанный адрес электронной почты соответствует ранее зарегистрированному пользователю.
Вот как это выглядит в действии:

Вы можете узнать больше о валидации Exist и ее перестановках здесь .
Валидаторы файлов и изображений
Далее я покажу вам примеры FileValidator , который обеспечивает существование, MIME-тип и размер загружаемого файла, и ImageValidator , который проверяет изображение и его свойства.
Чтобы изучить валидаторы файлов и изображений, давайте рассмотрим пример из серии « Построение стартапа с помощью PHP» : настройки пользователя, изображения профилей и контактные данные . В этом эпизоде в модели UserSettings мы разрешаем пользователям загружать файл для своего изображения профиля.
Атрибут изображения принимает загруженный файл:
|
01
02
03
04
05
06
07
08
09
10
11
12
|
public function rules()
{
return [
[[‘user_id’, ], ‘required’],
[[‘user_id’, ], ‘unique’],
[[‘image’], ‘safe’],
[[‘image’], ‘file’, ‘extensions’=>’jpg, gif, png’],
[[‘image’], ‘file’, ‘maxSize’=>’100000’],
[‘image’, ‘image’, ‘extensions’ => ‘png, jpg, gif’,
‘minWidth’ => 100, ‘maxWidth’ => 400,
‘minHeight’ => 100, ‘maxHeight’ => 400,
],
|
FileValidators гарантирует, что изображение заканчивается с надлежащим расширением изображения и составляет менее 100 000 байтов.
ImageValidator также проверяет тип расширения, а также диапазоны ширины и высоты изображения.
Вот пример ошибок, возникающих при загрузке изображения, размеры которого превышают 400 x 400 пикселей:

Это мой помощник, который любил копировать мои уроки.
Диапазон в валидаторе
Также есть RangeValidator, который гарантирует, что значение находится в списке допустимых записей.
Для нашего примера давайте добавим поле для цензуры обратно в форму:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
<div class=»sample-form»>
<?php $form = ActiveForm::begin();
<?= $form->errorSummary($model);
<?= $form->field($model, ‘thought’)->textInput([‘maxlength’ => 255]) ?>
<?= $form->field($model, ’email’)->textInput()->label(Yii::t(‘app’,’Your email address’)) ?>
<?= $form->field($model, ‘url’)->textInput()->label(Yii::t(‘app’,’Your website’)) ?>
<?= $form->field($model, ‘censorship’)->textInput() ?>
<?= $form->field($model, ‘rank’)->textInput() ?>
<?= $form->field($model, ‘captcha’)->widget(\yii\captcha\Captcha::classname(), [
// configure additional widget properties here
]) ?>
|
Затем мы добавим RangeValidator, чтобы соответствовать ответу на строку да или нет :
|
1
2
3
4
5
6
7
8
9
|
public function rules()
{
return [
[[‘thought’], ‘string’, ‘max’ => 255],
[‘thought’, ‘match’, ‘pattern’ => ‘/^[az][A-Za-z,;\»\\s]+[!?.]$/i’,’message’=>Yii::t(‘app’,’Your thoughts should form a complete sentence of alphabetic characters.’)],
[[’email’], ’email’],
[[’email’], ‘exist’,’targetClass’=>’\app\models\User’,’message’=>Yii::t(‘app’,’Sorry, that person hasn\’t registered yet’)],
[[‘url’], ‘url’],
[‘censorship’, ‘in’, ‘range’ => [‘yes’,’no’,’Yes’,’No’],’message’=>Yii::t(‘app’,’The censors demand a yes or no answer.’)],
|
Вот пример RangeValidator в действии:

Валидатор совпадений регулярных выражений
Далее, давайте посмотрим на RegularExpressionValidator , который выполняет проверку по условию, определенному регулярным выражением.
В нашем примере я использую следующее регулярное выражение для сопоставления полных предложений с буквенными символами. Это означает, что они должны заканчиваться либо (!,? Или.) И не иметь числовых символов.
|
1
2
3
4
5
|
public function rules()
{
return [
[[‘thought’], ‘string’, ‘max’ => 255],
[‘thought’, ‘match’, ‘pattern’ => ‘/^[az][A-Za-z,;\»\\s]+[!?.]$/i’,’message’=>Yii::t(‘app’,’Your thoughts should form a complete sentence of alphabetic characters.’)],
|
Вот пример пользовательского ввода, который не проходит тест из-за цифр и отсутствия конечного знака препинания:

Вот правильное предложение:

Возможно, вас также заинтересуют Восемь регулярных выражений, которые вы должны знать (Tuts +), как справочник по распространенным шаблонам регулярных выражений.
Уникальный Валидатор
Наконец, давайте рассмотрим UniqueValidator , который гарантирует, что значение является уникальным в таблице, такой как адрес электронной почты или слаг.
Ранее в этой серии я рассмотрел SluggableBehavior , который предлагает собственную встроенную поддержку уникальности. Однако давайте рассмотрим еще пару примеров из серии « Построение стартапа с помощью PHP» .
В базе кода для Планировщика собраний (из более поздних обучающих выпусков) в модели Place ( \frontend\models\Place.php ) мы используем уникальный валидатор несколькими способами:
|
01
02
03
04
05
06
07
08
09
10
11
12
|
public function rules()
{
return [
[[‘name’,’slug’], ‘required’],
[[‘place_type’, ‘status’, ‘created_by’, ‘created_at’, ‘updated_at’], ‘integer’],
[[‘name’, ‘google_place_id’, ‘slug’, ‘website’, ‘full_address’, ‘vicinity’], ‘string’, ‘max’ => 255],
[[‘website’], ‘url’],
[[‘slug’], ‘unique’],
[[‘searchbox’], ‘unique’,’targetAttribute’ => ‘google_place_id’],
[[‘name’, ‘full_address’], ‘unique’, ‘targetAttribute’ => [‘name’, ‘full_address’]],
];
}
|
Во-первых, мы используем уникальное правило со слагом для дополнения SluggableBehavior, который является избыточным; но вы можете увидеть формат проверки.
Во-вторых, мы проверяем, что результаты окна поиска автозаполнения Google Адресов приводят к тому, что скрытое поле для google_place_id уникально, поскольку его еще нет в таблице мест. Мы по существу предотвращаем дублирование идентификаторов Google Place.
Важным моментом является то, что уникальный валидатор Yii2 позволяет нам применять уникальность в видимом поле (поле searchbox ), одновременно searchbox его во вторичном столбце, возвращаемом через AJAX от Google ( google_place_id ).
В-третьих, мы гарантируем, что name и full_address уникальны. Другими словами, дублированные названия мест в порядке. Там может быть базиллион Starbucks. Однако мы не хотим, чтобы кто-нибудь дважды заходил в одно и то же место Starbucks.
Примечание: кофе Starbucks не является эффективным стимулятором для разработчиков программного обеспечения. Я призываю вас посещать независимые кофейни.
Вот пример этого в действии:

Что дальше?
Я надеюсь, что вы согласны с тем, насколько просты и полезны валидаторы Yii2 для веб-разработки. Я просто не могу себе представить, что когда-нибудь вернусь к разработке ванильного PHP без помощи фреймворка.
Следите за будущими уроками в моей серии «Программирование с Yii2», поскольку я продолжаю изучать различные аспекты фреймворка. В следующем эпизоде я собираюсь рассмотреть расширенные функции проверки Yii2, такие как:
- Условная проверка для выполнения правила проверки только в том случае, если определенное событие является истинным
- Пользовательские валидаторы для создания необходимых проверок помимо того, что предлагает Yii из коробки
- Проверка на стороне клиента для использования встроенной в Yii проверки ActiveForm JavaScript без необходимости обновления страницы
- Проверка AJAX для реализации проверок AJAX на стороне сервера для расширения возможностей проверки страниц JavaScript на стороне клиента Yii.
- События проверки для отмены проверки или выполнения определенных функций до и / или после проверки
- Определение сценариев для выборочного применения правил в определенных ситуациях
- Специальная проверка для использования правил проверки независимо от отправки формы
Я приветствую тематические и тематические запросы. Вы можете опубликовать их в комментариях ниже, связаться со мной @reifman в Twitter или написать мне в Lookahead Consulting .
Если вы хотите узнать, когда появится следующий учебник по Yii2, вы также можете проверить мою страницу инструктора Tuts + . Он всегда содержит ссылки на мои статьи сразу после их публикации.
Ссылки по теме
- Руководство Yii2 по проверке пользовательского ввода
- Yii2 Руководство по основным валидаторам
- Валидаторы Yii2 (Документация)
- Yii2 Developer Exchange , мой собственный ресурсный сайт Yii2