Baigudin Software avatar
Baigudin Software logo
home
ru region
en region

PHP DOM Builder API 2.0

BOOS Core представлено для ARM микропроцессоров Texas Instruments семейства AM18x

Проект Baigudin Software представил операционное ядро BOOS Core для ARM микропроцессоров семейства AM18x компании Texas Instruments.

Работа с полями формы

Все мы знаем, что создать форму с полями ввода — это практически ничто. С этими полями необходимо работать. Хорошо, когда мы их обрабатываем на стороне пользователя, но это удобно только пользователю. В конечном итоге, он всё равно пошлёт эти данные на сервер. И вот тут нам необходимо их проанализировать, обработать, ведь мы же не доверяем тому, что прислал нам браузер пользователя, и был ли это браузер…

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

Ваш отзыв

Как нас нашли?:

* Имя:

E-mail:

Файл:

Комментарий:

Передать разработчикам:

* - Поле, обязательное для заполнения

Для соблюдения общего стиля нашего сайта, мы её обработали только CSS стилями, а вся вёрстка исключительно из примера.

Для полного понимания давайте создадим новый проект. Пусть в корневой директории нашего сервера лежат два файла index.php и Form.php, а также папка DomBuilder с нашей библиотекой.

Вот исходный код файла index.php:

<?php
// Добавляем http заголовок
header('Content-type: text/html; charset=utf-8');
//Подключаем внешние файлы:
require_once('DomBuilder/Elements.php');
require_once(
'Form.php');
// Импортируем пространство имен
use DomBuilder\Element as Element;
// Тип документа
Element::docType(Element::DOC_XHTML_10);
// Признак сжатия документа
Element::docCompress(false);
// Установка языковой зоны
Element::docLanguage('ru');
// Признак печати ошибок:
Element::printError(true);
// Создаём документ:
$document Element::create();
$document->insert('html')->insert('head')->after('body');
// Пусть валидатор скажет: "no warnings, no errors" :)
$document->find('head')
  ->
insert('title')->html('PHP DOM Builder form test')
  ->
after('meta')
  ->
attr('http-equiv''Content-Type')
  ->
attr('content''text/html; charset=utf-8');
// Добавляем форму
$document->find('body')->insertForm::get() );
// Выводим документ
echo Element::getDocument($document);
?>

Тут, пожалуй, ничего особо интересного. Мы просто подключаем необходимые для работы файлы и создаём документ.

Исходный код файла Form.php:

<?php
/**
 * Пример работы с формой.
 * 
 * @author    Sergey Baigudin, baigudin@mail.ru
 * @copyright 2014-2016 Sergey Baigudin
 * @license   http://baigudin.software/license/
 * @link      http://baigudin.software
 */ 

use DomBuilder\Element as Element;
class 
Form
{
  
/** 
   * Получение формы.
   * 
   * @return Element форма ввода.
   */  
  
static public function get()
  {
    
$form self::_form();
    if( 
self::_isChecked($form) ) self::_save($form);
    return 
$form
  }
  
/** 
   * Создание формы.
   * 
   * @return Element форма ввода.
   */  
  
static private function _form()
  {
    
// Создаём форму
    
$form Element::create('form')->action('')->method('post')
      ->
enctype('multipart/form-data');
    
// Создаём сообщение
    
$form->insert('p')->addClass('message')->html('Ваш отзыв');
    
// Создаём SELECT
    
$form->insert('p')->insert('ext/str')->html('Как нас нашли?: ')
      ->
after('select')
        ->
insert('option')->value(0)
        ->
after('option')->value(1)->html('В поисковике')
        ->
after('option')->value(2)->html('В соцсети')
        ->
after('option')->value(3)->html('На форуме')
        ->
after('option')->value(4)->html('Шёл, шёл и нашел')
        ->
after('option')->value(5)->html('Другое');
    
// Создаём INPUT type=text для имени
    
$form->insert('p')->insert('ext/str')->html('* Имя: ')
      ->
after('input/text')
      ->
fill(true)
      ->
maxlength(30);
    
// Создаём INPUT type=text для E-main
    
$form->insert('p')->insert('ext/str')->html('E-mail: ')
      ->
after('input/text')
      ->
reg('^[a-zA-Z0-9_\-\.]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$')
      ->
maxlength(30);      
    
// Создаём INPUT type=file
    
$form->insert('p')->insert('ext/str')->html('Файл: ')
      ->
after('input/file')
      ->
fileSize(1024102400); 
    
// Создаём TEXTAREA          
    
$form->insert('p')->insert('ext/str')->html('Комментарий: ')
      ->
after('textarea');    
    
// Создаём INPUT type=checkbox
    
$form->insert('p')->insert('ext/str')->html('Передать разработчикам: ')
      ->
after('input/checkbox');      
    
// Создаём INPUT type=submit
    
$form->insert('input/submit')->value('Отправить');
    
// Создаем сноску
    
$form->insert('p')->addClass('fill')
      ->
html('* - Поле, обязательное для заполнения');      
    return 
$form;
  }  
  
/** 
   * Проверка корректности полей формы.
   * 
   * @param Element $form форма ввода.
   * @return bool результат проверки формы.
   */  
  
static private function _isChecked($form)
  {
    
// Проверяем, что форма была отправлена
    
if($form->find('input[type=submit]')->value() === false
      return 
false;
    
// Находим все поля, кроме кнопки submit
    
$list $form->find('input, select, textarea')
      ->
not('input[type=submit]');
    
$error false;
    
// Проверка полей на ошибки
    
for($i=0$i<$list->length(); $i++) 
    {
      
$node $list->get($i);
      
$error |= $node->check()->error();  
      if( 
$node->error() == true self::_message($node);
    }
    return !
$error;
  }
  
/** 
   * Вывод сообщения об ошибке.
   * 
   * @param Element $node узел поля ввода.   
   */  
  
static private function _message($node)
  {
    
$nodeName $node->prev()->html();
    
$errorStr $node->errorStr();
    
// Находим тег P с class=message и добавляем строку ошибки
    
$node->parents('form')->find('p.message')
      ->
insert('span')->addClass('error')->html("Поле $nodeName $errorStr")
      ->
after('br');
  }
  
/** 
   * Сохранение результата формы
   * 
   * @param Element $form форма ввода.  
   */  
  
static private function _save($form)
  {
    
$span $form->find('p.message')
      ->
insert('span')->addClass('complete')
      ->
after('br')
      ->
prev();
    
// Если checkbox не установлен, то выходим
    
if($form->find('input[type=checkbox]')->get(0)->value() === false
    {
      
$span->html('Отзыв заполнен, но нам не отправлен');
      return;
    }
    
$span->html('Спасибо за Ваш отзыв!');
    
// ...
    // Тут мы сохраним Ваш отзыв
    // ...
  
}  
}

?>

Файл Form.php, как собственно и любое классовое программирование, основанное на автозагрузке и пространстве имен, содержит единственный класс – Form. Разве что класс этот описан в глобальном пространстве и к автозагрузке особого отношения не имеет. Все его методы – статические, но нам пока другого и не надо. Он имеет единственный общедоступный метод Form::get, который, как говорилось ранее, возвращает объект класса Element, содержащий в себе дерево объектов, формирующих форму ввода. А теперь давайте по порядку.

Сам по себе метод get ничего особого не делает. Вызывает метод создания базовой формы (Form::_form), проверяет поля формы на корректность (Form::_isChecked) и, если всё хорошо, сохраняет данные полей (Form::_save), возвращая эту самую форму.

Но, чтобы было что и на что проверять, нам необходимо настроить все поля – эта процедура реализована в методе Form::_form. Как и в HTML, для описания этих полей есть три класса:Element\Input, Element\Textareaи Element\Select. Класс Element\Inputимеет дочерние классы, соответствующие типу поля ввода, например Element\Input\Text. Каждый класс содержит набор свойств и методов для его уникальной настройки, работы с результатом, а также для автоматического формирования атрибутов поля в зависимости от полученных в запросе данных. Таким образом, создав класс, нам не стоит беспокоиться, чем его проинициализировать. Он автоматически возьмёт данные своего поля из запроса. Более тонкую настройку классов можно посмотреть в документации, а здесь хотелось бы отметить следующие методы:

  • fill – установка признака обязательного заполнения поля. По умолчанию он установлен в false;
  • reg – установка строки регулярного выражения, для проверки введенных пользователем данных;
  • maxlength – установка максимального количества символов поля ввода. Если атрибут отсутствует, то проверка не осуществляется;
  • fileSize – установка допустимых размеров принимаемого файла.

Каждый класс для работы с полями ввода имеет метод value, который возвращает значения поля из запроса. Если значение отсутствует, метод возвращает false. Таким образом, в методе Form::_isChecked мы проверяем факт отправки данных формы.

Проверка полей формы на корректность осуществляется вызовом метода check, а результат возвращает метод error. Если в результате проверки была обнаружена ошибка, то строку ошибки можно получить, вызвав метод errorStr, что мы и делаем при формировании сообщения об ошибки.

Если все поля ввода заполнены корректно, мы сохраняем данные полей, метод – Form::_save.

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

К предыдущей статье

К списку статей

К следующей статье