CodeIgniter 2 на русском

Класс Form Validation

CodeIgniter предоставляет всеобъемлющие проверки и подготовку данных, что помогает свести к минимуму объем кода, который вы будете писать.

 

Обзор

Перед тем, как объяснять подход CodeIgniter к валидации данных, давайте опишем идеальный сценарий:

  1. Отображается форма.
  2. Вы заполняете и отправляете ее.
  3. Если вы заполнили что-то неправильно, или возможно пропустили требуемый элемент, форма отображается снова. При этом она содержит уже введенные данные с сообщениями о произошедших ошибках, описывающими случившуюся проблему.
  4. Процесс продолжается до тех пор, пока вы не заполните форму правильно.

Принимающий скрипт должен:

  1. Проверить заполнение "обязательных" полей.
  2. Проверить тип полученных данных, и соответствие критериям корректности. Например, если отправлено имя пользователя, оно должно содержать только разрешенные символы. Строка должна быть больше минимальной длины, и меньше максимальной. Имя пользователя не должно совпадать с существующим именем, или с зарезервированным словом. И т.д.
  3. Дезинфицировать данные с целью безопасности.
  4. Переформатировать данные, если требуется (Обрезаны лишние пробелы в начале и конце строк? Детранслирован HTML? Т.д.)
  5. Подготовить данные к хранению в БД.

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

 

Учебник по валидации форм

Далее следует "настольный" учебник по валидации CodeIgniters.

Для работы вам нужны три вещи:

  1. Файл отображения с формой.
  2. Отображение, содержащее "успешное" сообщение, которое должно выводиться после успешной отправки.
  3. Функция контроллера для того, чтобы принимать и обрабатывать данные.

Давайте создадим эти три вещи, используя типичную форму для регистрации в качестве примера.

Форма

Используя текстовый редактор, создайте форму в файле с названием myform.php. Поместите файл в директорию applications/views/:

Страница успеха

Используя текстовый редактор, создайте файл с названием formsuccess.php и поместите его в директорию applications/views/:

Контроллер

Используя текстовый редактор, создайте файл с названием form.php и поместите его в директорию applications/controllers/:

Попробуйте!

Для того, чтобы попробовать вашу форму, посетите ваш сайт по URL, вроде следующего:

example.com/index.php/form/

Если вы просто отправите форму, не заполняя поля, вы должны увидеть ее перезагрузку. Это произошло потому, что вы не установили каких-то правил валидации.

Так как вы не сказали классу Form Validation, что необходимо что-то проверять, он возвращает FALSE (boolean false) по умолчанию. Функция run() возвращает TRUE только если успешно выполняются заданные вами правила, без каких-то исключений.

Объяснение

Выше вы увидели несколько вещей:

Форма form (myform.php)- это почти стандартная форма, за некоторыми исключениями:

  1. Используется помощник form для создания формы. Технически, это не обязательно. Вы можете создавать формы, используя HTML. Однако, выгода в использовании помощника заключается в том, что он генерирует action URL, основанный на URL, указанный в вашем конфигурационном файле. Это делает ваше приложение более портативным в случае, когда изменятся URL. (Прим. пер.: никто не мешает использовать относительные пути URL, начинающиеся с одиночного слеша /)
  2. В верху формы вы видите такую функцию: <?php echo validation_errors(); ?>

    Эта функция вернет сообщения об ошибках валидации. Если ошибок нет — будет пустая строка.

Контроллер (form.php) имеет функцию index(). Эта функция инициализирует класс валидации, загружает помощник form и помощник URL, использованный в ваших отображениях. Он также запускает процесс валидации. Если валидация успешна, выводится страница с сообщением об успехе.

Установка правил валидации

CodeIgniter позволяет вам задавать множество правил валидации, изменять их порядок, и в то же время позволяет подготавливать и обрабатывать данные полей. Для установки правил используйте функцию set_rules():

$this->form_validation->set_rules();

Эта функция имеет три параметра на входе:

  1. Имя поля — существующее имя, которое вы даете полю формы.
  2. Читаемое имя для этого поля, которое будет вставлено рядом с текстом сообщения. Например, если ваше поле называется "user", вы можете дать ему читаемое имя "Имя пользователя". Примечание: Если вы хотите, чтобы имя поля сохранялось в языковом файле, пожалуйста, прочтите Перевод имен полей.
  3. Правила валидации для поля формы.


Вот пример. В вашем контроллере (form.php) добавьте код, после инициализации валидации:

$this->form_validation->set_rules('username', 'Имя пользователя', 'required');
$this->form_validation->set_rules('password', 'Пароль', 'required');
$this->form_validation->set_rules('passconf', 'Повтор пароля', 'required');
$this->form_validation->set_rules('email', 'Почта', 'required');
after

Теперь ваш контроллер выглядит примерно так:

Если вы теперь отправите форму с пустыми полями, увидите сообщения об ошибках. Если вы заполните все поля, получите страницу с сообщением об успехе (success page).

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

Использование правил, заданных в массиве

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

$config = array(
               array(
                     'field'   => 'username',
                     'label'   => 'Имя пользователя',
                     'rules'   => 'required'
                  ),
               array(
                     'field'   => 'password',
                     'label'   => 'Пароль',
                     'rules'   => 'required'
                  ),
               array(
                     'field'   => 'passconf',
                     'label'   => 'Повтор пароля ',
                     'rules'   => 'required'
                  ),   
               array(
                     'field'   => 'email',
                     'label'   => 'Почта',
                     'rules'   => 'required'
                  )
            );

$this->form_validation->set_rules($config);

Сцепление правил

CodeIgniter позволяет вам соединять вместе несколько правил. Давайте попробуем. Измените ваши правила в третьем параметре функции, вот так:

$this->form_validation->set_rules('username', 'Имя пользователя', 'required|min_length[5]|max_length[12]');
$this->form_validation->set_rules('password', 'Пароль', 'required|matches[passconf]');
$this->form_validation->set_rules('passconf', 'Повтор пароля', 'required');
$this->form_validation->set_rules('email', 'Почта', 'required|valid_email');

Этот код устанавливает несколько правил:

  1. Строка в поле "имя пользователя" не должна быть короче 5 или длиннее 12 символов.
  2. Должны совпадать пароль и подтверждение пароля.
  3. Поле "Почта" должно содержать правильный адрес электронной почты.

Попробуйте! Отправьте вашу форму с некорректными данными и вы увидите сообщения об ошибках, соответствующие вашим новым правилам. Есть множество правил, которые вы можете увидеть ниже.

Подготовка данных

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

$this->form_validation->set_rules('username', 'Имя пользователя', 'trim|required|min_length[5]|max_length[12]|xss_clean');
$this->form_validation->set_rules('password', 'Пароль', 'trim|required|matches[passconf]|md5');
$this->form_validation->set_rules('passconf', 'Подтверждение пароля', 'trim|required');
$this->form_validation->set_rules('email', 'Почта', 'trim|required|valid_email');

В этом примере мы "обрезаем" строки, конвертируем пароль в MD5, и прогоняем имя пользователя через фильтр "xss_clean", который удаляет опасные данные.

Любая родная функция PHP, которая принимает один параметр, может быть использована как правило. Например, htmlspecialchars, trim, MD5 и так далее.

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

Перезаполнение формы

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

set_value('field name')

Откройте ваше отображение myform.php и измените значения в каждом поле, используя функцию set_value():

Не забудьте включить имя каждого поля в функцию set_value()!

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

Примечание: Справочник функций содержит функции, которые позволяют устанавливать меню <select>, переключатели radio и флаги checkbox.

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

<input type="text" name="colors[]" value="<?php echo set_value('colors[]'); ?>" size="50" />

Дополнительная информация в разделе Использование массивов в качестве имен полей.

Обратные вызовы (callbacks): ваши собственные функции валидации

Система валидации поддерживает обратные вызовы (callbacks) к вашим собственным функциям. Это позволяет вам расширить класс валидации для удовлетворения ваших потребностей. Например, если вам нужно сделать запрос в базу данных, чтобы проверить, что имя пользователя свободно, вы можете создать callback функцию, которая сделает это. Давайте попробуем сделать пример.

В вашем контроллере измените правило для "имени пользователя" так:

$this->form_validation->set_rules('username', 'Имя пользователя', 'callback_username_check');

Потом добавьте новую функцию username_check в ваш контроллер. Вот так он теперь будет выглядеть:

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

Для вызова callback просто поместите имя функции в правило, с префиксом "callback_".

Вы также можете обработать данные формы, переданные в вашу функцию, и вернуть их. Если ваш callback возвращает что-то кроме TRUE или FALSE, это понимается как новые данные для отображения в поле формы.

Установка сообщений об ошибке

Все родные сообщения об ошибках находятся в языковом файле: language/english/form_validation_lang.php

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

$this->form_validation->set_message('rule', 'Сообщение об ошибке');

Где rule соответствует имени конкретного правила, и Error Message — текст сообщения об ошибке.

Если вы добавите %s в сообщение об ошибке, это будет заменено читабельным именем, которое вы указываете при установке правил для поля.

В примере callback выше, сообщения об ошибках установлены передачей имени поля в функцию:

$this->form_validation->set_message('username_check')

Вы также можете переопределить любое сообщение об ошибке, которое найдете в языковом файле. Например, для того, чтобы изменить сообщение об "обязательности" поля, сделайте так:

$this->form_validation->set_message('required', 'Ваше собственное сообщение');

Перевод имен полей

Если вы хотите сохранить "читабельные" имена в языковом файле и, следовательно, позволить именам быть переводимыми, сделайте так:

Во-первых, добавьте префикс вашему "читабельному" имени lang:, как в этом примере:

$this->form_validation->set_rules('first_name', 'lang:first_name', 'required');

Затем сохраните имя в массиве, в одном из ваших языковых файлов (но без префикса):

$lang['first_name'] = 'Имя';

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

$this->lang->load('file_name');

Смотрите Класс Language для дополнительной информации о языковых файлах.

Изменение разделителей в сообщениях об ошибках

По умолчанию класс валидации использует тег абзаца (<p>) вокруг каждого сообщения об ошибке. Вы можете изменять эти разделители глобально или индивидуально.

  1. Глобальное изменение разделителей

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

    $this->form_validation->set_error_delimiters('<div class="error">', '</div>');

    В этом примере мы используем теги div.

  2. Индивидуальное изменение разделителей

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

    <?php echo form_error('field name', '<div class="error">', '</div>'); ?>

    или

    <?php echo validation_errors('<div class="error">', '</div>'); ?>

Раздельный показ ошибок

Если вы предпочитаете показывать ошибки под каждым полем, а не списком, вы можете использовать функцию form_error().

Попробуйте! Измените вашу форму, как показано здесь:

Если ошибок нет, ничего не будет показано. Если есть ошибки — появятся и сообщения.

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

Пометка! <?php echo form_error('options[size]'); ?>
<input type="text" name="options[size]" value="<?php echo set_value("options[size]"); ?>" size="50" />

Более подробную информацию смотрите в разделе Использование массивов в качестве имен полей.

 

Сохранение правил валидации в конфигурационном файле

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

Как сохранить ваши правила

Для того, чтобы сохранить ваши правила валидации, просто создайте файл с именем form_validation.php в вашей директории application/config/. В этом файле разместите массив с именем $config с вашими правилами. Как показано ранее, массив соответствует этому прототипу:

$config = array(
               array(
                     'field'   => 'username',
                     'label'   => 'Имя пользователя',
                     'rules'   => 'required'
                  ),
               array(
                     'field'   => 'password',
                     'label'   => 'Пароль',
                     'rules'   => 'required'
                  ),
               array(
                     'field'   => 'passconf',
                     'label'   => 'Подтверждение пароля',
                     'rules'   => 'required'
                  ),   
               array(
                     'field'   => 'email',
                     'label'   => 'Почта',
                     'rules'   => 'required'
                  )
            );

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

Вы ОБЯЗАНЫ назвать массив $config.

Создание наборов правил

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

$config = array(
                 'signup' => array(
                                    array(
                                            'field' => 'username',
                                            'label' => 'Имя пользователя',
                                            'rules' => 'required'
                                         ),
                                    array(
                                            'field' => 'password',
                                            'label' => 'Пароль',
                                            'rules' => 'required'
                                         ),
                                    array(
                                            'field' => 'passconf',
                                            'label' => 'Повтор пароля',
                                            'rules' => 'required'
                                         ),
                                    array(
                                            'field' => 'email',
                                            'label' => 'Почта',
                                            'rules' => 'required'
                                         )
                                    ),
                 'email' => array(
                                    array(
                                            'field' => 'emailaddress',
                                            'label' => 'Адрес почты',
                                            'rules' => 'required|valid_email'
                                         ),
                                    array(
                                            'field' => 'name',
                                            'label' => 'Имя',
                                            'rules' => 'required|alpha'
                                         ),
                                    array(
                                            'field' => 'title',
                                            'label' => 'Название',
                                            'rules' => 'required'
                                         ),
                                    array(
                                            'field' => 'message',
                                            'label' => 'Сообщение',
                                            'rules' => 'required'
                                         )
                                    )                          
               );

Вызов конкретной группы правил

Для того, чтобы вызвать конкретную группу, передайте ее имя функции run(). Например, чтобы вызвать правила signup, сделайте так:

if ($this->form_validation->run('signup') == FALSE)
{
   $this->load->view('myform');
}
else
{
   $this->load->view('formsuccess');
}

Связывание функции контроллера с группой правил

Альтернативный (и более автоматизированный) способ вызова группы правил — это ее именование в соответствии с именем функции контроллера, которую вы будете использовать. Например, давайте скажем, что контроллер называется Member, а функция — signup. Вот так может выглядеть ваш класс:

<?php

class Member extends CI_Controller {

   function signup()
   {      
      $this->load->library('form_validation');
            
      if ($this->form_validation->run() == FALSE)
      {
         $this->load->view('myform');
      }
      else
      {
         $this->load->view('formsuccess');
      }
   }
}
?>

Назовите группу правил member/signup в вашем конфигурационном файле:

$config = array(
           'member/signup' => array(
                                    array(
                                            'field' => 'username',
                                            'label' => 'Имя пользователя',
                                            'rules' => 'required'
                                         ),
                                    array(
                                            'field' => 'password',
                                            'label' => 'Пароль',
                                            'rules' => 'required'
                                         ),
                                    array(
                                            'field' => 'passconf',
                                            'label' => 'Повторите пароль',
                                            'rules' => 'required'
                                         ),
                                    array(
                                            'field' => 'email',
                                            'label' => 'Почта',
                                            'rules' => 'required'
                                         )
                                    )
               );

Когда группа правил называется идентично с классом/функцией контроллера, она будет использована автоматически при вызове функции run() из этого класса/функции.

 

Использование массивов в качестве имен полей

Класс Form Validation поддерживает использование массивов в качестве имен полей. Изучите этот пример:

<input type="text" name="options[]" value="" size="50" />

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

Например, чтобы установить правило для поля выше, вы будете использовать:

$this->form_validation->set_rules('options[]', 'Options', 'required');

Или, чтобы показать ошибку, вы будете использовать:

<?php echo form_error('options[]'); ?>

Перезаполнение формы:

<input type="text" name="options[]" value="<?php echo set_value('options[]'); ?>" size="50" />

Вы можете использовать многомерные массивы в качестве имен полей. Например:

<input type="text" name="options[size]" value="" size="50" />

Или:

<input type="text" name="sports[nba][basketball]" value="" size="50" />

Как и в нашем первом примере, вы должны использовать точное имя массива в функции-помощнике:

<?php echo form_error('sports[nba][basketball]'); ?>

Если вы используете флаги (checkboxes) или другие типы полей, которые допускают множественный выбор, не забудьте оставить пустую скобку после каждой опции, так как в этом случае все выделенное будет добавлено в массив POST:

<input type="checkbox" name="options[]" value="red" />
<input type="checkbox" name="options[]" value="blue" />
<input type="checkbox" name="options[]" value="green" />

или для многомерного массива:

<input type="checkbox" name="options[color][]" value="red" />
<input type="checkbox" name="options[color][]" value="blue" />
<input type="checkbox" name="options[color][]" value="green" />

Если вы используете функции помощника, также добавляйте скобки:

<?php echo form_error('options[color][]'); ?>

Справка по правилам

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

Правило Параметр Описание Пример
required Возвращает FALSE, если элемент формы пуст.  
matches Да Возвращает FALSE, если элемент формы не соответствует указанному элементу в параметре. matches[form_item]
min_length Да Возвращает FALSE, если элемент формы короче, чем указано в параметре. min_length[6]
max_length Да Возвращает FALSE, если элемент формы длиннее, чем указано в параметре. max_length[12]
exact_length Да Возвращает FALSE, если длина не соответствует указанному в параметре. exact_length[8]
alpha Нет Возвращает FALSE, если элемент формы содержит что-либо, кроме алфавитных символов.  
alpha_numeric Нет Возвращает FALSE, если элемент формы содержит что-нибудь, кроме алфавитных символов и цифр.  
alpha_dash Нет Возвращает FALSE, если элемент формы содержит что-нибудь, кроме алфавитных символов, цифр, знаков подчеркивания или тире.  
numeric Нет Возвращает FALSE, если элемент формы содержит что-нибудь, кроме цифр  
integer Нет Возвращает FALSE, если элемент формы содержит что-нибудь, кроме целых чисел.  
is_natural Нет Возвращает FALSE, если элемент формы содержит что-нибудь, кроме натуральных чисел 0, 1, 2, 3 и т.д.  
is_natural_no_zero Нет Возвращает FALSE, если элемент формы содержит что-нибудь, кроме натуральных чисел, кроме ноля 1, 2, 3, 4 и т.д.  
valid_email Нет Возвращает FALSE, если элемент формы не содержит правильного адреса электронной почты.  
valid_emails Нет Возвращает FALSE, если элемент формы не содержит списка правильных адресов электронной почты, разделенных запятыми.  
valid_ip Нет Возвращает FALSE, если элемент формы не содержит правильный IP-адрес.  
valid_base64 Нет Возвращает FALSE, если предоставленная строка содержит что-то, кроме правильных символов Base64.  

Примечания: Все эти функции могут быть вызваны самостоятельно. Например:

$this->form_validation->required($string);

Примечание: Вы также можете использовать родные функции PHP, которые принимают один параметр.

 

Справка по подготовке данных

Вот список доступных для использования функций:

Имя Параметр Описание
xss_clean Нет Пропускает данные через XSS-фильтр, описанный в Классе Input.
prep_for_form Нет Конвертирует специальные символы, которые могут разорвать форму.
prep_url Нет Добавляет "http://" к URLк, если требуется.
strip_image_tags Нет Обрезает теги HTML из тега изображения, оставляя только URL.
encode_php_tags Нет Конвертирует теги PHP в безопасные представления.

Примечание: Вы также можете использовать любые родные функции PHP, которые принимают один параметр. Например trim, htmlspecialchars, urldecode и так далее.

Справка по функциям

Слудующие функции предназначены для использования в вашем контроллере.

$this->form_validation->set_rules();

Позволяет устанавливать правила валидации, как описано в учебнике выше:

$this->form_validation->run();

Запускает процесс валидации. Возвращает булево TRUE при успехе, или FALSE при неудаче. Вы можете опционально передать имя группы правил в функцию, как разъяснено в Хранение групп правил в конфигурационном файле.

$this->form_validation->set_message();

Позволяет вам установить собственные сообщения об ошибках. Смотрите выше Установка сообщений об ошибках.

 

Справка по помощнику

Следующие функции помощника доступны для использования в файлах Отображений с вашими формами. Запомните, что это процедурные функции, поэтому они не требуют указывать при вызове $this->form_validation.

form_error()

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

<?php echo form_error('username'); ?>

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

validation_errors()

Показывает все ошибки как строку. Пример:

<?php echo validation_errors(); ?>

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

set_value()

Поволяет вам установить значения для input или textarea. Вы должны указать имя поля первым параметром. Второй (опциональный) параметр позволяет вам установить значение по умолчанию. Например:

<input type="text" name="quantity" value="<?php echo set_value('quantity', '0'); ?>" size="50" />

При первой загрузке будет показывать "0".

set_select()

Если вы используете меню <select>, эта функция позволит отображать элемент меню, который будет выбран. Первый параметр должен содержать имя меню, второй должен содержать значения каждого элемента, и третий (опциональный) параметр позволяет вам указать состояние элемента по умолчанию (используйте TRUE/FALSE).

Пример:

<select name="myselect">
<option value="one" <?php echo set_select('myselect', 'one', TRUE); ?> >One</option>
<option value="two" <?php echo set_select('myselect', 'two'); ?> >Two</option>
<option value="three" <?php echo set_select('myselect', 'three'); ?> >Three</option>
</select>

set_checkbox()

Позволяет вам выводить флаг (checkbox) в том состоянии, в котором он был перед отправкой формы. Первый параметр должен содержать имя флага, второй — его значение, и третий (опциональный) параметр позволяет вам указать состояние элемента по умолчанию (используйте TRUE/FALSE). Пример:

<input type="checkbox" name="mycheck[]" value="1" <?php echo set_checkbox('mycheck[]', '1'); ?> />
<input type="checkbox" name="mycheck[]" value="2" <?php echo set_checkbox('mycheck[]', '2'); ?> />

set_radio()

Позволяет вам показывать переключатель radio в состоянии, в котором он был перед отправкой формы. Эта функция идентична set_checkbox(), описанной выше.

<input type="radio" name="myradio" value="1" <?php echo set_radio('myradio', '1', TRUE); ?> />
<input type="radio" name="myradio" value="2" <?php echo set_radio('myradio', '2'); ?> />