Yii2 файл не проходит валидацию

Обновлено: 06.07.2024

Загрузка файлов в yii2 осуществляется через класс yii\web\UploadedFile. Для безопасной загрузки файла необходимо использовать стандартный функционал ActiveForm и моделей с заготовленными правилами валидации.

Стандартная реализация

На официальном сайте Yii2 приводится статья, следуя которой можно реализовать стандартный механизм загрузки файла на сайт. Следует заметить, что для загрузки файла создается собственная модель с правилами валидации, в качестве ответа $model->upload() должен возвратить не только true или false, а, например, название файла.

  • при росте проекта будет большая куча файлов, расположенных в одной папке, либо придется "плодить" большое количество моделей, ответственных за загрузку файлов.

Использование actions и виртуальной переменной

В данном примере понадобятся расширения yii2-file-kit и yii2-widget-fileinput.

Создадим виртуальную переменную $mainPicture в модели:

В web.config регистрируем компонент

В контроллере, который занимается созданием экземпляра articles (в бекенде) указываем actions:

Функция create примет вид:

Поле загрузки файла в форме создания статьи _form:

В данном случае, сохранение названия файла проходит через виртуальную переменную mainPicture в контроллере.

Обратите внимание на то, что используются события виджета FileInput.

Использование единого хранилища.

Данный способ отличается от предыдущего тем, что в таблице articles будем хранить не название файла, а его id. При такой реализации, в одной таблице базы данных будем хранить все загружаемые файлы, следовательно, для загрузки файлов можно будет использовать один и тот же action. Этот экшн при сохранении будет возвращать только id загруженного файла.

Добавим миграцию и создадим для нее модель через gii

Изменим action, для этого вынесем его в отдельный файл (необходимо скопировать экшн trntv\filekit\actions\UploadAction из папки vendor и внести правки в функцию run):

Теперь в ответе $output будет содержаться id загруженного файла.

В контроллере указываем action:

В файле \_form.php изменим события:

Из недостатков двух последний методов - файл будет загружаться даже если не сохранять саму модель, поскольку action выполняется при обращении. В качестве решения возможно использование cron для автоочистки неиспользуемых файлов.

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

Учитывая модель данных которые должен заполнить пользователь, можно проверить эти данные на валидность воспользовавшись методом yii\base\Model::validate(). Метод возвращает логическое значение с результатом валидации ложь/истина. Если данные не валидны, ошибку можно получить воспользовавшись свойством yii\base\Model::$errors. Рассмотрим пример:

Правила проверки ¶

Для того, чтобы validate() действительно работал, нужно объявить правила проверки атрибутов. Правила для проверки нужно указать в методе yii\base\Model::rules(). В следующем примере показано, как правила для проверки модели ContactForm , нужно объявлять:

Метод rules() должен возвращать массив правил, каждое из которых является массивом в следующем формате:

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

  • Псевдонимы основного валидатора, например required , in , date и другие. Пожалуйста, обратитесь к списку Основных валидаторов за более подробной информацией.
  • Название метода проверки в модели класса, или анонимную функцию. Пожалуйста, обратитесь к разделу Встроенных валидаторов за более подробной информацией.
  • Полное имя класса валидатора. Пожалуйста, обратитесь к разделу Автономных валидаторов за более подробной информацией.

Правило может использоваться для проверки одного или нескольких атрибутов. Атрибут может быть проверен одним или несколькими правилами. Правило может быть применено только к определенным сценариям указав свойство on . Если вы не укажите свойство on , это означает, что правило будет применяться ко всем сценариям.

Когда вызывается метод validate() для проверки, он выполняет следующие действия:

  1. Определяет, какие атрибуты должны проверяться путем получения списка атрибутов от yii\base\Model::scenarios() используя текущий scenario. Эти атрибуты называются - активными атрибутами.
  2. Определяет, какие правила проверки должны использоваться, получив список правил от yii\base\Model::rules() используя текущий scenario. Эти правила называются - активными правилами.
  3. Каждое активное правило проверяет каждый активный атрибут, который ассоциируется с правилом. Правила проверки выполняются в том порядке, как они перечислены.

Согласно вышеизложенным пунктам, атрибут будет проверяться, если и только если он является активным атрибутом, объявленным в scenarios() и связан с одним или несколькими активными правилами, объявленными в rules() .

Примечание: Правилам валидации полезно давать имена. Например:

В случае наследования предыдущей модели, именованные правила можно модифицировать или удалить:

События валидации ¶

Когда вызывается метод yii\base\Model::validate() он инициализирует вызов двух методов, которые можно переопределить, чтобы настроить процесс проверки:

    : выполнение по умолчанию вызовет yii\base\Model::EVENT_BEFORE_VALIDATE событие. Вы можете переопределить этот метод, или обрабатывать это событие, чтобы сделать некоторую предобработку данных (например, форматирование входных данных), метод вызывается до начала валидации. Этот метод должен возвращать логическое значение, указывающее, следует ли продолжать проверку или нет. : выполнение по умолчанию вызовет yii\base\Model::EVENT_AFTER_VALIDATE событие. Вы можете либо переопределить этот метод или обрабатывать это событие, чтобы сделать некоторую постобработку данных (например, отформатировать данные удобным для дальнейшей обработки образом), метод вызывается после валидации.

Условные валидации ¶

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

Это свойство when принимает PHP callable функцию с следующим описанием:

Если вам нужна поддержка условной проверки на стороне клиента, вы должны настроить свойство метода whenClient, которое принимает строку, представляющую JavaScript функцию, возвращаемое значение определяет, следует ли применять правило или нет. Например:

Фильтрация данных ¶

Пользователь часто вводит данные которые нужно предварительно отфильтровать или предварительно обработать(очистить). Например, вы хотите обрезать пробелы вокруг username . Вы можете использовать правила валидации для достижения этой цели.

В следующих примерах показано, как обрезать пробелы во входных данных и превратить пустые входные данные в NULL с помощью trim и указать значения по умолчанию с помощью свойства default основного валидатора:

Вы также можете использовать более сложные фильтрации данных с помощью анонимной функции подробнее об этом filter.

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

Обработка пустых входных данных ¶

Если входные данные представлены из HTML-формы, часто нужно присвоить некоторые значения по умолчанию для входных данных, если они не заполнены. Вы можете сделать это с помощью валидатора default. Например:

По умолчанию входные данные считаются пустыми, если их значением является пустая строка, пустой массив или null . Вы можете реализовать свою логику определения пустых входящих данных путем переопределения метода yii\validators\Validator::isEmpty() используя анонимную функцию. Например:

Примечание: большинство валидаторов не обрабатывает пустые входные данные, если их yii\base\Validator::skipOnEmpty свойство принимает значение по умолчанию true . Они просто будут пропущены во время проверки, если связанные с ними атрибуты являются пустыми. Среди основных валидаторов, только captcha , default , filter , required , и trim будут обрабатывать пустые входные данные.

Специальная валидация ¶

Иногда вам нужно сделать специальную валидацию для значений, которые не связаны с какой-либо моделью.

Если необходимо выполнить только один тип проверки (например, проверка адреса электронной почты), вы можете вызвать метод validate() нужного валидатора. Например:

Примечание: Не все валидаторы поддерживают такой тип проверки. Примером может служить unique валидатор, который предназначен для работы с моделью.

Примечание: Свойство yii\base\Validator::skipOnEmpty используется только в yii\base\Model и использование его отдельно не будет иметь никакого эффекта.

Если необходимо выполнить несколько проверок в отношении нескольких значений, вы можете использовать yii\base\DynamicModel, который поддерживает объявление, как атрибутов так и правил "на лету". Его использование выглядит следующим образом:

Метод yii\base\DynamicModel::validateData() создает экземпляр DynamicModel , определяет атрибуты, используя приведенные данные ( name и email в этом примере), и затем вызывает yii\base\Model::validate() с данными правилами.

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

После валидации, вы можете проверить успешность выполнения вызвав метод hasErrors() и затем получить ошибки проверки вызвав метод errors как это делают нормальные модели. Вы можете также получить доступ к динамическим атрибутам, определенным через экземпляр модели, например, $model->name и $model->email .

Создание Валидаторов ¶

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

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

Встроенный валидатор наследует методы модели или использует анонимную функцию. Описание метода/функции:

Ниже приведены некоторые примеры:

Примечание: по умолчанию, встроенные валидаторы не будут применяться, если связанные с ними атрибуты получат пустые входные данные, или если они уже не смогли пройти некоторые правила валидации. Если вы хотите, чтобы, это правило применялось всегда, вы можете настроить свойства skipOnEmpty и/или skipOnError свойства false в правиле объявления. Например:

Автономные валидаторы ¶

Если вы хотите, чтобы ваш валидатор поддерживал проверку значений без модели, также необходимо переопределить yii\validators\Validator::validate(). Вы можете также переопределить yii\validators\Validator::validateValue() вместо validateAttribute() и validate() , потому что по умолчанию последние два метода реализуются путем вызова validateValue() .

Валидация на стороне клиента ¶

Проверка на стороне клиента на основе JavaScript целесообразна, когда конечные пользователи вводят входные данные через HTML-формы, так как эта проверка позволяет пользователям узнать ошибки ввода быстрее и таким образом улучшает ваш пользовательский интерфейс. Вы можете использовать или реализовать валидатор, который поддерживает валидацию на стороне клиента в дополнение к проверке на стороне сервера.

Информация: Проверка на стороне клиента желательна, но необязательна. Её основная цель заключается в предоставлении пользователям более удобного интерфейса. Так как входные данные, поступают от конечных пользователей, вы никогда не должны доверять верификации на стороне клиента. По этой причине, вы всегда должны выполнять верификацию на стороне сервера путем вызова yii\base\Model::validate(), как описано в предыдущих пунктах.

Использование валидации на стороне клиента ¶

Многие основные валидаторы поддерживают проверку на стороне клиента out-of-the-box. Все, что вам нужно сделать, это просто использовать yii\widgets\ActiveForm для построения HTML-форм.

Например, LoginForm ниже объявляет два правила: первое использует required основной валидатор, который поддерживается на стороне клиента и сервера; второе использует validatePassword встроенный валидатор, который поддерживается только на стороне сервера.

Класс yii\widgets\ActiveForm будет читать правила проверки заявленные в модели и генерировать соответствующий код JavaScript для валидаторов, которые поддерживают проверку на стороне клиента. Когда пользователь изменяет значение поля ввода или отправляет форму, JavaScript на стороне клиента будет срабатывать и проверять введенные данные.

Если вы хотите отключить проверку на стороне клиента полностью, вы можете настроить свойство yii\widgets\ActiveForm::$enableClientValidation установив значение false . Вы также можете отключить проверку на стороне клиента отдельных полей ввода, настроив их с помощью свойства yii\widgets\ActiveField::$enableClientValidation установив значение false .

Реализация проверки на стороне клиента ¶

Чтобы создать валидатор, который поддерживает проверку на стороне клиента, вы должны реализовать метод yii\validators\Validator::clientValidateAttribute() возвращающий фрагмент кода JavaScript, который выполняет проверку на стороне клиента. В JavaScript-коде, вы можете использовать следующие предопределенные переменные:

В следующем примере мы создаем StatusValidator который проверяет значение поля на соответствие допустимым статусам. Валидатор поддерживает оба способа проверки и на стороне сервера и на стороне клиента.

Подсказка: приведенный выше код даётся, в основном, чтобы продемонстрировать, как осуществляется поддержка проверки на стороне клиента. На практике вы можете использовать in основные валидаторы для достижения той же цели. Вы можете написать проверку, как правило, например:

Отложенная валидация ¶

Если Вам необходимо выполнить асинхронную проверку на стороне клиента, вы можете создавать Deferred objects. Например, чтобы выполнить пользовательские AJAX проверки, вы можете использовать следующий код:

В примере выше переменная deferred предусмотренная Yii, которая является массивом Отложенных объектов. $.get() метод jQuery создает Отложенный объект, который помещается в массив deferred .

Также можно явно создать Отложенный объект и вызвать его методом resolve() , тогда выполняется асинхронный вызов к серверу. В следующем примере показано, как проверить размеры загружаемого файла изображения на стороне клиента.

Примечание: метод resolve() должен быть вызван после того, как атрибут был проверен. В противном случае основная проверка формы не будет завершена.

Для простоты работы с массивом deferred , существует упрощенный метод add() , который автоматически создает Отложенный объект и добавляет его в deferred массив. Используя этот метод, вы можете упростить пример выше, следующим образом:

AJAX валидация ¶

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

Чтобы включить AJAX-валидацию для одного поля, Вы должны свойство enableAjaxValidation выбрать как true и указать уникальный id формы:

Чтобы включить AJAX-валидацию для всей формы, Вы должны свойство enableAjaxValidation выбрать как true для формы:

Примечание: В случае, если свойство enableAjaxValidation указано и у поля и у формы, первый вариант будет иметь приоритет.

Также необходимо подготовить сервер для обработки AJAX-запросов валидации. Это может быть достигнуто с помощью следующего фрагмента кода, в контроллере действий:

Приведенный выше код будет проверять, является ли текущий запрос AJAX. Если да, он будет отвечать на этот запрос, предварительно выполнив проверку и возвратит ошибки в случае их появления в формате JSON.

Информация: Вы также можете использовать Deferred Validation AJAX валидации. Однако, AJAX-функция проверки, описанная здесь более интегрированная и требует меньше усилий к написанию кода.

What You'll Be Creating

Если вы спрашиваете «Что такое Yii?», ознакомьтесь с моим предыдущим учебным пособием: Введение в Yii Framework, в котором рассматриваются преимущества Yii и которое включает обзор нового в Yii 2.0, выпущенного в октябре 2014 года.

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

В этих примерах мы продолжим использование кодовой базы приложения Hello, которую мы использовали в прошлых уроках. Используйте ссылки GitHub на этой странице, чтобы получить код.

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

Что такое Валидатор?

Если вы являетесь веб-разработчиком, вы, вероятно, знаете, что пользователю нельзя доверять. Например, пользователи могут использовать методы SQL-инъекций, чтобы попытаться запустить запросы, которые изменяют или раскрывают пароли. Кто-то однажды запустил SQL-инъекцию против установки PHPList с открытым исходным кодом и смог открыть один из моих паролей (PHPList сохранял их в виде обычного текста). Чаще всего вы просто хотите убедиться, что данные, которые пользователи предоставляют, соответствуют типам, формам и диапазонам вашего приложения.

Создание валидаторов в PHP вручную требует времени. Yii Framework предоставляет тонну базовых функций проверки, поэтому нет необходимости создавать их с нуля. Но, если вам нужны какие-то пользовательские расширения, это просто.

Валидации - еще одна причина, по которой я считаю, что всегда имеет смысл создавать приложения на веб-фреймворках, таких как Yii, а не на ванильном PHP.

В предыдущих эпизодах мы также много говорили о генераторе кода Yii - Gii. Одним из преимуществ Gii является то, что он напишет соответствующие правила проверки для ваших моделей на основе определений типа SQL в таблице. Это большая экономия времени.

Какие проверки поддерживает Yii?

Вот список встроенных валидаторов Yii и ссылки на документацию:

Как работает валидация Yii

Вот как Yii описывает поток проверки. Как правило, вы можете использовать сценарий по умолчанию и не нужно создавать свои собственные. Обычно вам нужно полагаться на Gii, чтобы генерировать правила или писать свои собственные.

Когда вызывается метод validate() , он делает следующие шаги для выполнения проверки:

  1. Определяет, какие атрибуты должны быть проверены путем получения списка атрибутов из yii\base\Model::scenarios() с использованием текущего сценария. Эти атрибуты называются активными атрибутами.
  2. Определяет, какие правила проверки следует использовать, получив список правил из yii\base\Model::rules(), используя текущий сценарий. Эти правила называются активными правилами.
  3. Использует каждое активное правило для проверки каждого активного атрибута, связанного с этим правилом. Правила проверки проверяются в том порядке, в котором они перечислены.

Согласно вышеуказанным шагам проверки атрибут будет проверяться, если и только если он является активным атрибутом, объявленным в scenarios() и связан с одним или несколькими активными правилами, объявленными в rules() .

Пример правил проверки модели

Вот как может выглядеть набор правил проверки модели. Я взял их из приложения Планировщик встреч, модель Place:

По мере дальнейшего использования наших собственных примеров валидации вы узнаете, что представляет собой каждое из приведенных выше определений.

Пример отображения ошибок

Существует несколько способов доступа к ошибкам, возвращаемым валидацией.

Вот пример получения массива ошибок в контроллере:

И вот пример использования функции Yii errorSummary в ActiveForms:

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

Using Yii errorSummary to display form errors
Using Yii errorSummary to display form errors
Using Yii errorSummary to display form errors

Расширенная проверка

В последующих эпизодах я также приведу примеры использования расширенных функций проверки:

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

Теперь давайте начнем с примеров различных встроенных валидаторов.

Базовые валидаторы полей

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

Подготовка модели с использованием миграции и Gii

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

Я создам Sample модель, чтобы создать примерную таблицу и проверки с помощью Gii. Вот код миграции:

Затем мы выполним миграцию:

Далее мы будем использовать генератор кода Yii для построения модели:

Validation Yiis Gii Model Generator
Validation Yiis Gii Model Generator
Validation Yiis Gii Model Generator

А затем CRUD файлы:

Validation Yiis Gii CRUD Generator
Validation Yiis Gii CRUD Generator
Validation Yiis Gii CRUD Generator

Gii генерирует эти правила проверки образца:

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

Required Validator

RequiredValidator гарантирует наличие значения. Вы можете увидеть это выше для полей: rank, censorship и occurred.

Validators Required With JavaScript Client Side Validation
Validators Required With JavaScript Client Side Validation
Validators Required With JavaScript Client Side Validation

Safe Validator

SafeValidator не является истинным валидатором. Он позволяет массовое присвоение переданной веб-формы для включения атрибута, например, $model->attributes = $_POST['Comment']. Или, в созданном Gii SampleController, вы можете увидеть этот код:

Без безопасного правила в Sample модели (или другого правила) указанное значение не будет присвоено атрибутам модели. Это уменьшает вероятность наличия дополнительного вектора атаки без преднамеренного кода.

Default Value Validator

DefaultValueValidator не является истинным валидатором. Он устанавливает значения по умолчанию для пустых полей.

Давайте изменим правило для occurred , чтобы установить значение даты по умолчанию с использованием текущей даты. Мы также удалим Required валидатор, чтобы позволить Default валидатору заполнить значение.

Когда мы создаем новый Sample и оставляем пустое поле occurred , вы можете увидеть, что результирующее представление включает текущую дату, заполненную валидатором значений по умолчанию.

Validators Default Value
Validators Default Value
Validators Default Value

Фильтры

FilterValidator также не является истинным валидатором. Он выполняет преобразование по предоставленному значению. Чаще всего вы можете использовать его, чтобы обрезать пробелы с концов строки.

FilterValidators определяются с помощью встроенных функций обратного вызова, таких как эта пользовательская функция проверки:

Поскольку trim - это функция PHP, мы можем просто объявить наше правило валидации строкой:

Если вы отправляете форму с начальными или конечными пробелами в поле thought, FilterValidator удалит их.

Теперь давайте посмотрим на некоторые встроенные валидаторы типов.

Валидаторы типов

Валидаторы типов гарантируют соответствие пользовательских данных определенным типам, часто тем, которые указаны в таблице базы данных. Gii автоматически сгенерирует их.

String Validator и Number Validator

StringValidator гарантирует, что значение является строкой. NumberValidator гарантирует, что значение является числовым, например, integer или float.

Ниже приведены примеры правил:

Я также временно удаляю Required валидатор, чтобы посмотреть, как работают строковые и числовые проверки.

Validators Number and String
Validators Number and String
Validators Number and String

Goodness со значением high выдает ошибку, потому что это не число, а rank со значением 27 проходит проверку. Censorship пуста (NULL), поэтому не выполняется проверка строки.

Boolean Validator

BooleanValidator обеспечивает значение true или false. Вы можете определить значения для true и false. Значение по умолчанию - целое число 0 или 1. Этот валидатор может быть более полезным, когда поле используется с выпадающим списком, например, Да / Нет.

Вот как я определил свое правило для Boolean:

Validators Boolean
Validators Boolean
Validators Boolean

Date Validator

DateValidator гарантирует, что значение является правильно отформатированной датой, которую можно настроить с помощью атрибута format. С Yii ActiveForm в настоящее время это проверка на стороне сервера. Поэтому я также добавил требуемое правило для поля Occurred.

Вот мои определения правил с валидатором даты для поля Occused:

Вот как это выглядит, когда мы отправляем форму:

Validators Date
Validators Date
Validators Date

Что дальше?

Следите за предстоящими уроками в моем курсе Программирование с Yii2, так как я продолжаю погружаться в разные аспекты структуры. В следующих двух эпизодах я проведу вас через оставшиеся валидаторы и покажу вам, как создавать продвинутые расширения для системы проверки Yii.

Вы также можете ознакомиться с моим курсом Построение стартапа с помощью PHP, в которой используется расширенный шаблон Yii2, когда я создаю реальное приложение.

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

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

Учитывая модель данных которые должен заполнить пользователь, можно проверить эти данные на валидность воспользовавшись методом [[yii\base\Model::validate()]] . Метод возвращает логическое значение с результатом валидации ложь/истина. Если данные не валидны, ошибку можно получить воспользовавшись методом [[yii\base\Model::errors]] . Рассмотрим пример:

Правила проверки

Для того, чтобы validate() действительно работал, нужно объявить правила проверки атрибутов. Правила для проверки нужно указать в методе [[yii\base\Model::rules()]] . В следующем примере показано, как правила для проверки модели ContactForm , нужно объявлять:

Метод должен [[yii\base\Model::rules()|rules()]] возвращать массив правил, каждое из которых является массивом в следующем формате:

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

  • Псевдонимы основного валидатора, например required , in , date и другие. Пожалуйста, обратитесь к списку Основных валидаторов за более подробной информацией.
  • Название метода проверки в моделе класса, или анонимную функцию. Пожалуйста, обратитесь к разделу Встроенных валидаторов за более подробной информацией.
  • Полное имя класса валидатора. Пожалуйста, обратитесь к разделу Автономных валидаторов за более подробной информацией.

Правило может использоваться для проверки одного или нескольких атрибутов. Атрибут может быть проверен одним или несколькими правилами. Правило может быть применено только к определенным сценариям указав свойство on . Если вы не укажите свойство on , это означает, что правило будет применяться ко всем сценариям.

Когда вызывается метод validate() для проверки, он выполняет следующие действия:

  1. Определяет, какие атрибуты должны проверяться путем получения списка атрибутов от [[yii\base\Model::scenarios()]] используя текущий [[yii\base\Model::scenario|scenario]] . Эти атрибуты называются - активными атрибутами.
  2. Определяет, какие правила проверки должны использоваться, получив список правил от [[yii\base\Model::rules()]] используя текущий [[yii\base\Model::scenario|scenario]] . Эти правила называются - активными правилами.
  3. Каждое активное правило проверяет каждый активный атрибут, который ассоциируется с правилом. Правила проверки выполняются в том порядке, как они перечислены.

Согластно вышеизложеным пунктам, атрибут будет проверяться, если и только если он является активным атрибутом, объявленных в scenarios() и связан с одним или несколькими активными правилами, объявленными в rules() .

События валидации

Когда вызывается метод [[yii\base\Model::validate()]] он инициализирует вызов двух методов, которые можно переопределить, чтобы настроить процесс проверки:

  • [[yii\base\Model::beforeValidate()]] : выполнение по умолчанию вызовет [[yii\base\Model::EVENT_BEFORE_VALIDATE]] событие. Вы можете переопределить этот метод, или обрабатывать это событие, чтобы сделать некоторую предобработку данных (например, форматирование входных данных), метод вызывается до начала валидации. Этот метод должен возвращать логическое значение, указывающее, следует ли продолжать проверку или нет.
  • [[yii\base\Model::afterValidate()]] : выполнение по умолчанию вызовет [[yii\base\Model::EVENT_AFTER_VALIDATE]] событие. Вы можете либо переопределить этот метод или обрабатывать это событие, чтобы сделать некоторую постобработку данных(Например, отформатировать данные удобным для дальнейшей обработки образом), метод вызывается после валидации.

Условные валидации

Для проверки атрибутов только при выполнении определенных условий, например если один атрибут зависит от значения другого атрибута можно использовать [[yii\validators\Validator::when|when]] свойство, чтобы определить такие условия. Например:

Это свойство [[yii\validators\Validator::when|when]] принимает PHP callable функциию с следующим описанием:

Если вам нужна поддержка условной проверки на стороне клиента, вы должны настроить свойство метода [[yii\validators\Validator::whenClient|whenClient]] которое принимает строку, представляющую JavaScript функцию, возвращаемое значение определяет, следует ли применять правило или нет. Например:

Фильтрация данных

Пользователь частво вводит данные которые нужно предварительно отфильтровать или предварительно обработать(очистить). Например, вы хотите обрезать пробелы вокруг username . Вы можете использовать правила валидации для достижения этой цели.

В следующих примерах показано, как обрезать пробелы в входных данных и превратить пустые входные данные в NULL с помощью trim и указать значения по умолчанию с помощью свойства default основного валидатора:

Вы также можете использовать более сложные фильтрации данных с помощью анонимной функции подробнее об этом filter.

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

Обработка пустых входных данных

Если входные данные представлены из HTML-формы, часто нужно присвоить некоторые значения по умолчанию для входных данных, если они не заполнены. Вы можете сделать это с помощью валидатора default. Например:

По умолчанию входные данные считаются пустыми, если их значением является пустая строка, пустой массив или null. Вы можете настроить значение по умолчанию с помощью свойства [[yii\validators\Validator::isEmpty]] используя анонимную функцию. Например:

Примечание: большинство валидаторов не обрабатывает пустые входные данные, если их [[yii\base\Validator::skipOnEmpty]] свойство принимает значение по умолчанию true. Они просто будут пропущены во время проверки, если связанные с ними атрибуты являются пустыми. Среди основных валидаторов, только captcha , default , filter , required , и trim будут обрабатывать пустые входные данные.

Специальная валидация

Иногда вам нужно сделать специальную валидацию для значений, которые не связаны с какой-либо модели.

Если необходимо выполнить только один тип проверки (например, проверка адреса электронной почты), вы можете вызвать метод [[yii\validators\Validator::validate()|validate()]] нужного валидатора. Например:

Примечание: Не все валидаторы поддерживают такой тип проверки. Примером может служить unique валидатор, который предназначен для работы с моделью.

Если необходимо выполнить несколько проверок в отношении нескольких значений, вы можете использовать [[yii\base\DynamicModel]] , который поддерживает объявление, как атрибутов так и правил " на лету". Его использование выглядит следующим образом:

Метод [[yii\base\DynamicModel::validateData()]] создает экземпляр DynamicModel , определяет атрибуты, используя приведенные данные ( name и email в этом примере), и затем вызывает [[yii\base\Model::validate()]] с данными правилами.

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

После валидации, вы можете проверить успешность выполнения вызвав метод [[yii\base\DynamicModel::hasErrors()|hasErrors()]] и затем получить ошибки проверки вызвав метод [[yii\base\DynamicModel::errors|errors]] как это делают нормальные модели. Вы можете также получить доступ к динамическим атрибутам, определенным через экземпляр модели, например, $model->name и $model->email .

Создание Валидаторов

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

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

Встроенный валидатор наследует методы модели или использует анонимную функцию. Описание метода/функции:

Ниже приведены некоторые примеры:

Примечание: по умолчанию, встроенные валидаторы не будет применяться, если связанные с ними атрибуты получат пустые входные данные, или если они уже не смогли пройти некоторые правила валидации. Если вы хотите, чтобы, что правило применялось всегда, вы можете настроить свойства [[yii\validators\Validator::skipOnEmpty|skipOnEmpty]] и/или [[yii\validators\Validator::skipOnError|skipOnError]] свойства false в правиле объявления. Например:

php [ ['country', 'validateCountry', 'skipOnEmpty' => false, 'skipOnError' => false], ]

Автономные валидаторы

Если вы хотите, чтобы ваш валидатор поддерживал проверку значений, без модели, также необходимо переопределить [[yii\validators\Validator::validate()]] . Вы можете также переопределить [[yii\validators\Validator::validateValue()]] вместо validateAttribute() и validate() , потому что по умолчанию последние два метода реализуются путем вызова validateValue() .

Валидация на строне клиента

Проверка на стороне клиента на основе JavaScript целесообразна, когда конечные пользователи вводят входные данные через HTML-формы, так как эта проверка позволяет пользователям узнать, ошибки ввода быстрее, и таким образом улучшает ваш пользовательский интерфейс. Вы можете использовать или реализовать валидатор, который поддерживает валидацию на стороне клиента в дополнение к проверке на стороне сервера.

Информация: Проверка на стороне клиента желательна, но необязательна. Её основная цель заключается в предоставлении пользователям более удобного интерфейса. Так как входные данные, поступают от конечных пользователей, вы никогда не должны доверять верификации на стороне клиента. По этой причине, вы всегда должны выполнять верификацию на стороне сервера путем вызова [[yii\base\Model::validate()]] , как описано в предыдущих пунктах.

Использование валидации на стороне клиента

Многие основные валидаторы поддерживают проверку на стороне клиента out-of-the-box. Все, что вам нужно сделать, это просто использовать [[yii\widgets\ActiveForm]] для построения HTML-форм.

Например, LoginForm ниже объявляет два правила: один использует required основные валидаторы, который поддерживается на стороне клиента и сервера; другой использует validatePassword встроенный валидатор, который поддерживается только на стороне сервера.

Класс [[yii\widgets\ActiveForm]] будет читать правила проверки заявленные в модели и генерировать соответствующий код JavaScript для валидаторов, которые поддерживают проверку на стороне клиента. Когда пользователь изменяет значение поля ввода или отправляет форму, JavaScript на стороне клиента будет срабатывать и проверять введеные данные.

Если вы хотите отключить проверку на стороне клиента полностью, вы можете настроить свойство [[yii\widgets\ActiveForm::enableClientValidation]] установив значение false. Вы также можете отключить проверку на стороне клиента отдельных полей ввода, настроив их с помощью свойства [[yii\widgets\ActiveField::enableClientValidation]] установив значение false.

Реализация проверки на стороне клиента

Чтобы создать валидатор, который поддерживает проверку на стороне клиента, вы должны реализовать метод [[yii\validators\Validator::clientValidateAttribute()]] возвращающий фрагмент кода JavaScript, который выполняет проверку на стороне клиента. В JavaScript-коде, вы можете использовать следующие предопределенные переменные:

В следующем примере мы создаем StatusValidator который проверяет, if an input is a valid status input against the existing status data. Валидатор поддерживает оба способа проверки и на стороне сервера и на стороне клиента.

Совет: приведенный выше код даётся, в основном, чтобы продемонстрировать, как осуществляется поддержка проверки на стороне клиента. На практике вы можете использовать in основные валидаторы для достижения той же цели. Вы можете написать проверку, как правило, например:

php [ ['status', 'in', 'range' => Status::find()->select('id')->asArray()->column()], ]

Отложенная валидация

Если Вам необходимо выполнить асинхронную проверку на стороне клиента, вы можете создавать Deferred objects. Например, чтобы выполнить пользовательские AJAX проверки, вы можете использовать следующий код:

В примере выше переменная deferred предусмотреная Yii, которая является массивом Отложенных объектов. $.get() метод jQuery создает Отложенный объект, который помещается в массив deferred .

Также можно явно создать Отложенный объект и вызвать его методом resolve() , тогда выполнется асинхронный вызов к серверу. В следующем примере показано, как проверить размеры загружаемого файла изображения на стороне клиента.

Примечание: метод resolve() должен быть вызван после того, как атрибут был проверен. В противном случае основная проверки формы не будет завершена.

Для простоты работы с массивом deferred , существует упрощенный метод add() , который автоматически создает Отложенный объект и добавляет его в deferred массив. Используя этот метод, вы можете упростить пример выше, следующим образом:

AJAX валидация

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

Чтобы включить AJAX-валидацию для всей формы, Вы должны свойство [[yii\widgets\ActiveForm::enableAjaxValidation]] выбрать как true и указать id формы:

Вы можете также включить AJAX валидацию или выключать для отдельных полей ввода, настроив их с помощью свойства [[yii\widgets\ActiveField::enableAjaxValidation]] .

Также необходимо подготовить сервер для обрабаботки AJAX-запросов валидации. Это может быть достигнуто с помощью следующего фрагмента кода, в контроллере действий:

Приведенный выше код будет проверять, является ли текущий запрос AJAX. Если да, он будет отвечать на этот запрос, предварительно выполнив проверку и возвратит ошибки в случае их появления в формате JSON.

Информация: Вы также можете использовать Deferred Validation AJAX валидации. Однако, AJAX-функция проверки, описанные здесь более интегрированая и требует меньше усилий к написанию кода.

Вот но на всякий случай и другие и другие методы
если не чего не менять ,то проходит без ошибки и такая картинка как в коде 'default.jpg'; есть.

public function uploadAvatar ( $filePath )
$file = UploadedFile :: getInstance ( $this , 'avatar' );

// if no file was uploaded abort the upload
if (empty( $file )) return false ;
> else

// file extension
$fileExt = $file -> extension ;
// purge filename
$fileName = Yii :: $app -> security -> generateRandomString ();
// update file->name
$file -> name = $fileName . ". < $fileExt >" ;
// update avatar field
$this -> avatar = $fileName . ". < $fileExt >" ;
// save images to imagePath
$file -> saveAs ( $filePath . $fileName . ". < $fileExt >" );

// the uploaded file instance
return $file ;
>
>

/**
* fetch stored image file name with complete path
*
* @return string
*/
public function getImagePath ()
return $this -> avatar ? Yii :: getAlias ( Yii :: $app -> getModule ( 'userextended' )-> avatarPath ). $this -> avatar : null ;
>

/**
* fetch stored image url
*
* @return string
*/
public function getImageUrl ()
if ( ! is_null ( $this -> getAccountAttributes ()) && ! $this -> avatar )
$imageURL = $this -> getSocialImage ();

$avatar = $this -> avatar ? $this -> avatar : 'default.jpg' ;
$imageURL = Yii :: getAlias ( Yii :: $app -> getModule ( 'userextended' )-> avatarURL ). $avatar ;
>

public function actionProfile ()
// Load Model
$model = $this -> finder -> findProfileById ( Yii :: $app -> user -> identity -> getId ());
// Load Old Image
$oldImage = $model -> avatar ;
// Load avatarPath from Module Params
$avatarPath = Yii :: getAlias ( Yii :: $app -> getModule ( 'userextended' )-> avatarPath );

// Create uploadAvatar Instance
$image = $model -> uploadAvatar ( $avatarPath );

// Ajax Validation
$this -> performAjaxValidation ( $model );

if ( $model -> load ( Yii :: $app -> request -> post ()) && $model -> save ())

// revert back if no valid file instance uploaded
if ( $image === false ) $model -> avatar = $oldImage ;
> else

// if is there an old image, delete it
if( $oldImage )
$model -> deleteImage ( $oldImage );
>

// upload new avatar
$model -> avatar = $image -> name ;
>

Yii :: $app -> getSession ()-> setFlash ( 'success' , Yii :: t ( 'user' , 'Your profile has been updated' ));

Читайте также: