Создание и валидация формы на фреймворке Kohana. Часть 1
Какие теги используются при создании формы я описывал в предыдущей статье. В этой статье я хочу описать как построить форму используя фреймворк Kohana. Я буду использовать только родные средства для построения и валидации формы. Есть много сторонних средств для работы с формой, но их описание выходит за рамки данной статьи.
На правах рекламы — интересный СЕО блог.
Для пример возьмем форму по этой ссылке.
Описание класса Form в Kohana
Для построения формы используется класс Form. Методы класса все статические, доступ к методам осуществляется через ::, например Form::input(…); Если так написать, то будет создан тег input и т.д.
Основная часть методов, которые формируют теги первым параметром принимает значение атрибута name,т.е. название переменной которое будет со своим значением передано на сервер. Вторым параметром принимается значение для создаваемого тега, для тега input это значение атрибута value, для тега select это массив, ключи которого есть значение тега option, а значение массива это то, что стоит между тегом option. Третьим параметров, в основном, принимается массив дополнительных атрибутов для создаваемого тега. Ключ массива это название атрибута, а значение массива — это значение атрибута, например array(‘id’=>’id_tag’).
Опишем более подробно.
Создание тега form
Для этого используется метод Form::open. В качестве первого аргумента он принимает значение атрибута action, но можно передавать NULL, тогда значение урла будут соответствовать текущей странице. Если передать пустоезнавение ‘ ‘, то тогда урл будет браться из переменной Kohana::base_url, которую мы задаем в bootstrap.php.
Вторым значение элемента передается массив других атрибутов для данного тега.
<!--?php echo Form::open(NULL, array('id'=-->'contact', 'enctype'=>'multipart/form-data'));?> будет выведено</pre> <form id="contact" action="/contact" method="post" enctype="multipart/form-data" accept-charset="utf-8">
Для закрытия тега формы применяется метод Form::close, он не принимает никаких параметров.
<!--?php echo Form::close();?--> будет выведено
Создание тега input
Для создание этого тега предназначен метод Form::input.
Первый параметр это название тега, т.е. значение атрибута name=’name’
Второй параметр это значение атрибута value=’value’
Третий параметр это массив с данными по атрибутам.
<!--?php echo Form::input('name', Security::xss_clean(Arr::get($_POST, 'name', '')), array('id'=-->'name'));?> будет выведено <input id="name" type="text" name="name" value="" />
В атрибутах можно передать тип для тега input и видоизменить форму, можно сделать тип пароль, чекбокс, рейдиобатон и тд, но есть и отдельные методы которые просто реализуют некоторые типы, наверное это сделано для удобства понимая кода. К таким метода относятся Form::hidden, Form::password, Form::file.
Для создания чекбосков используется метод Form::checkbox. Все параметры похожи, имя, значение, выбран или нет элемент и массив атрибутов. Особо можно выделить третий параметр $checked он принимает истину или ложь и показывает выбран данный элемент формы или нет.
<!--?php echo Form::radio('sex', 1, ((isset($_POST['sex']) AND $_POST['sex']==1) ? TRUE : FALSE), array('id'=-->'your_sex_mail'));?> <!--?php echo Form::checkbox('track', 0, (isset($_POST['track']) ? TRUE : FALSE), array('id'=-->'track'));?> будет выведено, соответственно <input id="your_sex_mail" type="radio" name="sex" value="1" /> <input id="track" type="checkbox" name="track" value="0" />
Создание тега textarea
Для создание этого тега предназначен метод Form::textarea.
Первый параметр это название тега, т.е. значение атрибута name=’name’
Второй параметр это сам текст который оказывается внутри тега.
Третий параметр это массив с данными по атрибутам.
Четвертый параметр предназначен для двойной кодировки спецсимволов, смотрите ф-цию htmlspecialchars
<!--?php echo Form::textarea('descr', Security::xss_clean(Arr::get($_POST, 'descr', '')), array('id'=-->'descr'));?> будет выведено, соответственно <textarea id="descr" name="descr" rows="10" cols="50"></textarea>
Создание тега select
Для создание этого тега предназначен метод Form::select.
Первый параметр это название тега, т.е. значение атрибута name=’name’
Второй параметр это массив с данными.
Третий параметр это или массив значений или значение выбранного элемента
Четвертый параметр это массив с данными по атрибутам.
Также этот тег позволяет построить вспомогательный элемент optgroup. Для его создания необходимо передавать массив, у которого в качестве ключа будет название группы а значение это будет вложенный массив ключ=>значение для элемента option.
<!--?php echo Form::select('type_error', array('0'=-->' ', '1'=>'изменение информации о сайте', '2'=>'стилистические, грамматические, орфогр. ошибки'), (isset($_POST['type_error']) ? $_POST['type_error'] : 0), array('id'=>'type_error'));?> будет выведено, соответственно <select name="type_error"> <option selected="selected" value="0"> </option></select> <select name="type_error"> <option value="1">изменение информации о сайте</option></select> <select name="type_error"> <option value="2">стилистические, грамматические, орфогр. ошибки</option></select>
Создание тега label
Первый параметр принимает значение ИД основного элемента формы, к которому привязан.
Второй элемент показывает описание к тегу.
Третий параметр — массив атрибутов.
<!--?php echo Form::label('email', __('Ваш эл. адрес').':'.'<span--> *');?> <!--?php echo Form::input('email', Security::xss_clean(Arr::get($_POST, 'email', ' ')), array('id'=-->'email'));?> будет выведено, соответственно <label for="email">Ваш эл. адрес:<span> *</span></label> <input id="email" type="text" name="email" value="" />
Остальные теги
В данном классе есть еще методы — submit, image, button. Все они являются частным случаем тегом input.
Пример построения формы
Тут привожу код вьюхи, формы которую рассматриваем.
</pre> <h1></h1> <pre> <!--?php echo Form::open(Request::instance()--->uri, array('id'=>'contact', 'enctype'=>'multipart/form-data'));?> <!--?php if(isset($errors) AND count($errors)-->0):?> <!--?php echo View::factory('errors')--->bind('errors', $errors)?> <!--?php endif;?--></pre> <div class="require"></div> <fieldset title="<?php echo __('Ваши данные');?><br />"> <legend><!--?php echo __('Ваши данные');?--></legend> <ul> <li><!--?php echo Form::label('name', __('Ваше имя').':'.'<span--> *');?> <!--?php echo Form::input('name', Security::xss_clean(Arr::get($_POST, 'name', '')), array('id'=-->'name'));?></li> <li><!--?php echo Form::label('email', __('Ваш эл. адрес').':'.'<span--> *');?> <!--?php echo Form::input('email', Security::xss_clean(Arr::get($_POST, 'email', '')), array('id'=-->'email'));?></li> <li class="sex"> <div></div> <!--?php echo Form::label('your_sex_mail', __('муж').':');?--> <!--?php echo Form::radio('sex', 1, ((isset($_POST['sex']) AND $_POST['sex']==1) ? TRUE : FALSE), array('id'=-->'your_sex_mail'));?> <!--?php echo Form::label('your_sex_femail', __('жен').':');?--> <!--?php echo Form::radio('sex', 0, ((isset($_POST['sex']) AND $_POST['sex']==0) ? TRUE : FALSE), array('id'=-->'your_sex_femail'));?></li> </ul> </fieldset> <fieldset title="<?php echo __('Ваш вопрос');?><br />"> <legend><!--?php echo __('Ваши вопрос');?--></legend> <ul> <li><!--?php echo Form::label('type_error', __('Описание проблемы').':'.'<span--> *');?> <!--?php echo Form::select('type_error', $type_error, (isset($_POST['type_error']) ? $_POST['type_error'] : 0), array('id'=-->'type_error'));?></li> <li><!--?php echo Form::label('descr', __('Описание проблемы').':'.'<span--> *');?> <!--?php echo Form::textarea('descr', Security::xss_clean(Arr::get($_POST, 'descr', '')), array('id'=-->'descr'));?></li> <li><!--?php echo Form::label('img', __('Картинка с ошибкой').':');?--> <!--?php echo Form::file('img', array('id'=-->'img'));?></li> <li><!--?php echo Form::label('track', __('Отслеживать вопрос').':');?--> <!--?php echo Form::checkbox('track', 0, (isset($_POST['track']) ? TRUE : FALSE), array('id'=-->'track'));?></li> </ul> </fieldset> <ul class="captcha"> <li></li> <li><!--?php echo Form::label('captcha', __('Введите код').':'.'<span--> *');?> <!--?php echo Form::input('captcha', NULL, array('id'=-->'captcha'));?></li> </ul> <div class="buttons"></div> <pre> <!--?php echo Form::close();?-->
Небольшое описание.
$errors — это переменная которая в себе будет нести ошибки при валидации формы;
Security::xss_clean(Arr::get($_POST, ‘descr’, »)) — это часть чистит вводимые значение от XSS, а также подставляет дефолтное значение если нет значение текущей переменной, а данном случае descr.
Описание контроллера, валидации приведу в следующей статье.
Статья просмотренна 148720 раз, зашло посетителей 34053
Прежде всего спасибо за хорошую статью ! Возможно вопрос несколько некорректен, но все же, зачем использовать этот класс для просто получить в конце ХТМЛ ? Какие его преимущества ? Ведь можно описать форму изначально как хтмл в стринге, и не нагружать сервер лишний раз.
Есть тут и своя логика! Например для вывода изображений можно просто писать тег img и не парить себе мозг, но что будет если изображение по ссылке пропало, стерли?! Будет дыра!
Если использовать перекрытый метод HTML::image, в своём классе, то можно сделать проверку на существование файла и если такого нет, то выводить картинку заглушку и записывать в лог сообщение об отсутствующем файле.
Возможно в дальнейшем понадобиться добавить атрибут id который будет равен атрибуту name, в простом описании хтмля прийдется все переписывать, а так написал пару строчек в классе и все как надо.
Возможно в дальнешем сразу завяжут валидацию и построение формы в один класс, как это есть в ZendFramework.
спасибо за статью. Я вот думаю, не могу понять, как при такой вьюхе будет обстоять дело с версткой. Ведь верстальщик не понимая пхп ногу сломает, или не так?
Обычно верстальщик дает программисту полностью сверстанную форму на xHTML и CSS, а потом уже программер заменяет часть тегов (если нужно) на свой код. Иногда наоборот, делает все программер, а потом верстальщик подходит и говорит, для каких элементов какие классы нужно поставить. Если где-то "тупим" — спроси или познай.
Раньше тоже задавался таким вопросом, зачем использовать этот хелпер, но недавно опробовал его в действии и понравилось, прежде всего в плане удобности. К примеру, нужно вывести в мульти select массив категорий и сразу сделать отмеченными несколько из них (для отмеченных категорий тоже должен быть массив). Делается просто:
<?php echo form::label('category', 'Категория') ?>
<span><?php echo form::select('category[]', $categories, $post['cats'], array('id' => 'category')) ?></span>
где $categories массив всех категорий в виде array('value' => 'name', …), а $post['cats'] — массив категорий которые должны быть отмеченными.
Все выглядит очень аккуратно и понятно, и не нужны никакие foreach(…), if(…). Как то так..
И, к стати, параметр multiply для select добавляется автоматически, если 3-й параметр ($post['cats']) — массив.
А не подскажете как в css проверить фоновые изображения?
Ну стерли или потеряли — что делать, а их там сотни!
проверить средствами css наличие или отсутствие файла на сервере нет возможности, т.к. файл находиться на сервере, а стили, яваскрипт срабатывают у клиента.
Единственное как можно проверить, это сделать файл с расширением css исполняем для рнр (смотрим в сторону апача), далее пишем функцию для обработки файлов и уже делаем выводы…
На текущий момент форма не работает Class 'Validate' not found или так и было задумано
Через полтора года я написал новую статью о работе валидации во фреймворке Kohana 3.3.0
<?php echo Form::select('type_error', array('0'=>' ', '1'=>'изменение информации о сайте', '2'=>'стилистические, грамматические, орфогр. ошибки'), (isset($_POST['type_error']) ? $_POST['type_error'] : 0), array('id'=>'type_error'));?>
будет выведено, соответственно
<select id="type_error" name="type_error">
<option value="0" selected="selected"> </option>
<option value="1">изменение информации о сайте</option>
<option value="2">стилистические, грамматические, орфогр. ошибки</option>
</select>
Какое значение <option v1> и <option v2> тут передается Post -ом…. Почему везде type_error ?
В первой строке передается массив, так ключи этого массива и будут v1, v2 и тд, а значения будет то, что между <option></option>. Значения массива видят юзеры, ключи машины.
type_error это название переменой в форме, в данном случает тип select имеет название type_error .
ЗЫ Вообще-то это самые азы html-form