如何使用OOP动态构建PHP表单?

时间:2008-11-13 22:44:19

标签: php oop class forms

我将如何创建一个真实世界的表单创建类,我可以用它来显示一个包含不同类型字段的新表单,因为我想要多少字段,我可以使用dropdown,我可以通过以下方式完成所有这些操作使用OOP?

5 个答案:

答案 0 :(得分:8)

老实说,考虑到PHP有一些成熟的表单包,我不会自己动手。

我为PHP4站点使用PEAR的HTML_QuickForm包(http://pear.php.net/manual/en/package.html.html-quickform.php)。

对于PHP5,我将查看Zend_Form(http://framework.zend.com/manual/en/zend.form.html)。

对于我的quickform代码,我使用了一个帮助器类,它允许我使用配置数组定义表单。例如:

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'实际上是多个表单字段(基本上是元类型)。这就是我对这个帮助类的喜爱 - 我可以用它们的规则定义一组标准字段(例如地址,credit_card等),它们可以以一致的方式在很多页面上使用。

答案 1 :(得分:7)

你绝对可以。考虑一个Form类,它存储有关表单本身的信息:methodactionenctype属性。还可以在顶部输入类似可选标题和/或描述文本的内容。当然,您还需要一组输入元素。这些可能会被放入他们自己的类中(虽然它们为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。

答案 2 :(得分:1)

仅供参考,Khurram Khan的Object Oriented Forms是PHP的优秀OO表单实现。

以下是代码的示例:

$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实例。

答案 3 :(得分:1)

我会反对其他建议并建议您构建自己的库来生成表单。如果你失败了,你仍然会在这个过程中学到很多东西。

设计过程在这里最为重要。你从顶部开始,问问自己表格上的内容。在抽象层面,表格中充满了元素。有些是可见的,有些是不可见的,有些可以由用户输入,但有些则不能,有些元素可以触发其他元素......并且列表继续...

最终你会得到装饰性的元素。 (文本,标题,分隔符,字段集,链接,图像),交互的元素(输入,下拉菜单,复选框,单选按钮,提交按钮),最后是既不装饰也不交互的元素(隐藏输入,锚点和作为元素的元素)用于分组其他元素的容器。)

一旦组织了不同的类别,您就开始研究所有元素都具有的功能,并将其放入基本元素类中。然后你上升链使你的类做得越来越多,继承其他更简单的元素类。在我的库中,基本元素类称为form_element,每个form_element都有一个唯一的名称,同一表单中的其他元素都不能具有该名称。 form_element还具有一组属性。它有一个函数,所有元素都调用render()。在基类中,render()不执行任何操作(因此基本元素始终不可见),但在派生类中,它开始生成HTML。顺便说一句,我从来没有让我的任何类创建HTML。相反,我有一个名为html的静态类,它为所有需要其服务的类编写HTML。

在表单元素链的早期,您应该有一个容器,用于组合其他元素。它应该有一个add()函数,它的render()函数应该包括调用其所有子元素的render()函数。表单类将从此容器类派生。

在设计上花费充足的时间。注意与库的其余部分的兼容性。

如果希望表单中的数据来自数据库并保存到数据库中,则需要添加此功能并将表单元素类链接到表和列。在这里,我有一个单独的DB类,可以检索/保存数据。我有一个创建查询的查询类。表单元素应与创建HTML,创建查询或访问数据库无关。我的静态类DB和我的查询类负责脏工作。表单类只应包含表单内容。表单类将需要保存的字段的所有表和列收集到一个数组中,并将其传递给创建查询的查询类,然后将该查询传递给执行它的DB类。

一旦你正确设置,正确设计的课程突然变得非常容易。

因为你有一个可以编写HTML的类,你的表单类只需要html :: init()并使用render()跟随它,并且表单的整个HTML代码在html缓冲区中可用。 html :: output()刷新所有内容。

验证也在外部使用静态验证类处理。可以验证的表单元素以可以直接传递给验证类的格式在数组中保存验证指令。需要验证的每个元素都绑定到一个error元素,如果元素没有验证则显示错误,如果一切顺利,则会保持不可见。

这是为了向您展示在设计表单环境(或其他任何内容)时,您真正需要在开始之前考虑所有内容。您投入的工作可能不会立即转化为可以为您的应用程序提供动力的代码,但它肯定会使您成为更好的开发人员,从而使您未来的项目更容易处理。

表单类创建表单,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()函数完全处理所有内容,从数据库中检索数据,将表单呈现到视图中,验证数据并将其保存回数据库。

以编程方式创建表单(如上所述)的一个优点是可以编写自己的基于表单的代码生成器来创建用于创建表单的代码。

我希望这可以帮助你或其他人。

答案 4 :(得分:0)

您绝对应该使用OO PHP来编写表单,以及所有其他HTML输出。我找不到任何PHP库(这些答案中的许多链接都已消失)来做我想要的事情,所以我写了PHPFUI。它不是通用的HMTL输出库,而是输出Foundation CSS Framework的页面。您可以轻松地使用相同的技术来输出更原始的页面,Bootstrap或任何其他内容。我不想编写通用的HTML OO PHP库,因为出于性能方面的考虑,我想要一些精简和有意义的内容。另外,我也不喜欢过度设计工程师,因此很难将其编码为Foundation。但是,同样的原理也适用于任何希望输出干净的HTML而没有任何验证问题的PHP库,而这些问题通常是手写的HTML。