Baigudin Software avatar
Baigudin Software logo
home
ru region
en region

PHP DOM Builder API 2.0

Выпущен релиз EOOS Automotive R22-07 в версия v0.9.0

Первый официальный релиз EOOS Automotive, который был тщательно проработан для POSIX и WIN32 совместимых операционных систем с учетом интерфейсов разработанных для EOOS RT – операционной системы реального времени.

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

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

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

Ваш отзыв

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

* Имя:

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.

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

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

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

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