Статьи

Как программировать с Yii2: специализированные валидации

Конечный продукт
Что вы будете создавать

Если вы спрашиваете: «Что такое 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.

Начнем с CaptchaValidator, который проверяет, есть ли правильный ответ на поле проверки CAPTCHA . CAPTCHA помогают гарантировать, что человек заполняет форму, надеясь, что автоматизированные сценарии не будут отправлять ее.

Вот пример Yii Captcha в действии:

Валидаторы Yii2 Валидатор 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 в действии:

Образец валидатора Yii2 Ошибка проверки 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’ => ‘<=’],
       ];
   }

Вы можете увидеть полный список доступных операторов сравнения здесь .

Вот как выглядит наша форма, когда пользователь отправляет неверный атрибут:

Валидаторы Yii2 Сравнить

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

Валидаторы Yii2 Валидатор сравнения с пользовательским сообщением об ошибке

Реализация этого довольно проста с добавлением атрибута сообщения:

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.

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’)) ?>

Вот валидаторы в действии:

Валидаторы Yii2 Валидаторы электронной почты и URL

Это, безусловно, очень полезно для веб-приложений.

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, чтобы убедиться, что указанный адрес электронной почты соответствует ранее зарегистрированному пользователю.

Вот как это выглядит в действии:

Валидаторы Yii2 существуют с поиском по электронной почте

Вы можете узнать больше о валидации 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 пикселей:

Проверка изображений и файлов в Yii2 Validators

Это мой помощник, который любил копировать мои уроки.

Также есть 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 в действии:

Диапазон валидаторов Yii2 в валидаторе

Далее, давайте посмотрим на 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.’)],

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

Ошибка регулярного выражения валидатора Yii2

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

Успешное совпадение регулярных выражений в Yid2 Validator

Возможно, вас также заинтересуют Восемь регулярных выражений, которые вы должны знать (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 Validators Уникальный

Я надеюсь, что вы согласны с тем, насколько просты и полезны валидаторы Yii2 для веб-разработки. Я просто не могу себе представить, что когда-нибудь вернусь к разработке ванильного PHP без помощи фреймворка.

Следите за будущими уроками в моей серии «Программирование с Yii2», поскольку я продолжаю изучать различные аспекты фреймворка. В следующем эпизоде ​​я собираюсь рассмотреть расширенные функции проверки Yii2, такие как:

  • Условная проверка для выполнения правила проверки только в том случае, если определенное событие является истинным
  • Пользовательские валидаторы для создания необходимых проверок помимо того, что предлагает Yii из коробки
  • Проверка на стороне клиента для использования встроенной в Yii проверки ActiveForm JavaScript без необходимости обновления страницы
  • Проверка AJAX для реализации проверок AJAX на стороне сервера для расширения возможностей проверки страниц JavaScript на стороне клиента Yii.
  • События проверки для отмены проверки или выполнения определенных функций до и / или после проверки
  • Определение сценариев для выборочного применения правил в определенных ситуациях
  • Специальная проверка для использования правил проверки независимо от отправки формы

Я приветствую тематические и тематические запросы. Вы можете опубликовать их в комментариях ниже, связаться со мной @reifman в Twitter или написать мне в Lookahead Consulting .

Если вы хотите узнать, когда появится следующий учебник по Yii2, вы также можете проверить мою страницу инструктора Tuts + . Он всегда содержит ссылки на мои статьи сразу после их публикации.