Как построить форму PHP динамически с ООП? - PullRequest
4 голосов
/ 14 ноября 2008

Как мне создать класс создания форм реального мира, который я могу использовать для отображения новой формы с полями разных типов, например, сколько полей я хочу, я могу использовать раскрывающиеся списки и все это можно сделать используя ООП?

Ответы [ 4 ]

8 голосов
/ 14 ноября 2008

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

Я использую пакет PEAR HTML_QuickForm (http://pear.php.net/manual/en/package.html.html-quickform.php) для сайтов PHP4.

Для PHP5 я бы заглянул в Zend_Form (http://framework.zend.com/manual/en/zend.form.html).

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

echo QuickFormHelper::renderFromConfig(array(
  'name' => 'area_edit',
  'elements' => array(
    'area_id'           => array('type' => 'hidden'),
    'active'            => array('type' => 'toggle'),
    'site_name'         => array('type' => 'text'),
    'base_url'          => array('type' => 'text'),
    'email'             => array('type' => 'text'),
    'email_admin'       => array('type' => 'text'),
    'email_financial'   => array('type' => 'text'),
    'cron_enabled'      => array('type' => 'toggle'),
    'address'           => array('type' => 'address'),
  ),
  'groups' => array(
    'Basic Details'   => array('site_name', 'base_url'),
    'Address Details' => array('address'),
    'Misc Details'    => array(), // SM: Display the rest with this heading.
  ),
  'defaults' => $site,
  'callback_on_success' => array(
    'object' => $module,
    'function' => 'saveSite',
   ),
));

Обратите внимание, что вышеприведенные типы элементов 'address' и 'toggle' на самом деле являются множественными полями формы (в основном, мета-типами). Это то, что мне нравится в этом вспомогательном классе - я могу определить стандартную группу полей с их правилами (например, адрес, кредитная карта и т. Д.), И они могут использоваться на многих страницах согласованным образом.

7 голосов
/ 14 ноября 2008

Вы определенно можете. Рассмотрим класс Form, в котором хранится информация о самой форме: атрибуты method, action, enctype. Также добавьте такие элементы, как дополнительный заголовок и / или текст описания вверху. Конечно, вам также понадобится массив элементов ввода. Вероятно, их можно поместить в их собственный класс (хотя их подклассы для InputText, InputCheckbox, InputRadio могут быть немного выше). Вот смутный дизайн скелета:

class Form {
    var $attributes,    // array, with keys ['method' => 'post', 'action' => 'mypage.php'...]
        $heading,
        $description,
        $inputs        // array of FormInput elements
    ;

    function render() {
        $output = "<form " . /* insert attributes here */ ">"
              . "<h1>" . $this->heading . "</h1>"
              . "<p>" . $this->description . "</p>"
        ;
        // wrap your inputs in whatever output style you prefer:
        // ordered list, table, etc.
        foreach ($this->inputs as $input) {
            $output .= $input->render();
        }
        $output .= "</form>";
        return $output;
    }
}

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

1 голос
/ 22 октября 2016

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

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

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

Как только вы организовали различные категории, вы начинаете изучать функции, которые есть у всех элементов, и вы можете поместить их в класс базовых элементов. Затем вы идете вверх по цепочке, заставляя ваши классы делать все больше и больше, наследуя от других более простых классов элементов. В моей библиотеке базовый класс элементов называется form_element, и каждый form_element имеет уникальное имя, которое не может иметь другой элемент в той же форме. Form_element также имеет набор атрибутов. У него есть функция, которую все элементы вызвали render (). В базовом классе render () ничего не делает (поэтому базовый элемент всегда невидим), но в производных классах он начинает создавать HTML. Кстати, я никогда не заставляю ни один из моих классов создавать HTML. Вместо этого у меня есть статический класс с именем html, который записывает HTML для всех классов, которым нужны его сервисы.

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

Потратьте много времени на дизайн. Обратите внимание на совместимость с остальной частью вашей библиотеки.

Если вы хотите, чтобы данные из формы приходили из базы данных и сохранялись в одну, вам нужно будет добавить эту функцию и связать класс элементов формы с таблицей и столбцом. Здесь также у меня есть отдельный класс БД, который может извлекать / сохранять данные. У меня есть класс запросов, который создает запросы. Элементы формы не должны иметь ничего общего с созданием HTML, созданием запросов или доступом к базе данных. Мой статический класс DB и мой класс запросов позаботятся о грязной работе. Класс формы должен быть связан только с материалом формы. Класс формы собирает в массив все таблицы и столбцы для полей, которые необходимо сохранить, и передает его в класс запросов, который создает запрос, который затем передается классу БД, который его выполняет.

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

Поскольку у вас есть класс, который может писать HTML, ваш класс формы должен просто html :: init () и следовать за ним с помощью render (), и весь HTML-код формы доступен в буфере html. html :: output () сбрасывает все.

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

Это должно показать вам, что когда вы разрабатываете среду формы (или что-то еще), вам действительно нужно учитывать абсолютно все, прежде чем начать. Работа, которую вы вкладываете в нее, может не сразу преобразоваться в код, который может привести ваше приложение в действие, но, несомненно, сделает вас гораздо лучшим разработчиком, тем самым сделав ваши будущие проекты намного проще в управлении.

Класс формы создает форму, класс html создает HTML, класс запросов выполняет запросы, а класс DB обрабатывает базу данных. Если ваши классы начинают выполнять работу, которую должны выполнять отдельные классы, у вас есть проблема с дизайном.

Вот пример кода, показывающий, как работает моя библиотека форм:

$fm = new form('myform');
$fm->binding(FORM_DATABASE);
$fm->state(FORM_RETRIEVE); 
$fm->set_recno(1);
$fm->add(new form_heading("My form"));
$fm->add($el=new form_input("name",40));
$el->bind_data('mytable','mycolumn');
$el->set_attribute('size', 25);
$el->set_default('Name');
$fm->add($el=new form_submit("submit_btn","Submit"));
if($fm->manage())
 {
 redirect or do something else here. The interaction with the form is done. The initial state for the form was FORM_RETRIEVE. If it had been FORM_NEW it would have displayed default values instead of the retrieved record and saved the form as a new record in the table. 
 }

Обратите внимание, что функция manage () формы заботится обо всем, извлекает данные из базы данных, отображает форму в представлении, проверяет данные и сохраняет их обратно в базу данных.

Одним из преимуществ программного создания форм (как описано выше) является возможность написать собственный генератор кода на основе форм для создания кода для создания форм.

Надеюсь, это поможет вам или кому-то еще.

1 голос
/ 04 июня 2012

Просто для справки, Объектно-ориентированные формы от Хуррама Кхана - отличная реализация ОО-форм для PHP.

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

$form = new Form("Register", "form.php"); 

$personal = new Block("Personal Information"); 

$name = new Text("name", "Your name"); 
$name->setDescription("this is my description"); 
$name->addValidator(new MaxLengthValidator("The name you have entered is too long", 30)); 

...

Еще одна более популярная реализация - PHPlib . Однако я нахожу это немного неуклюжим; кажется, что это просто стандартное функциональное программирование, заключенное в класс.

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

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