实现表单工厂

表单工厂的目的是从单个配置数组中生成一个可用的表单对象。表单对象应该能够检索它所包含的单个元素,以便生成输出。

如何做...

1.首先,让我们创建一个名为Application\Form\Factory的类来包含工厂代码。它将只有一个属性,$elements和一个getter

namespace Application\Form;

class Factory
{
  protected $elements;
  public function getElements()
  {
    return $this->elements;
  }
  // 剩余代码
}

2. 在我们定义主要的表单生成方法之前,重要的是要考虑我们计划接收什么配置格式,以及表单生成到底会产生什么。在这个例子中,我们将假设生成将产生一个Factory实例,有一个$elements属性。这个属性将是一个Application\Form\GenericApplication\Form\Element类的数组。

3. 我们现在准备好处理generate()方法。这将循环浏览配置数组,创建适当的Application\Form\GenericApplication\Form\Element\*对象,这些对象将被存储在$elements数组中。新方法将接受配置数组作为参数。将这个方法定义为静态的方法是很方便的,这样我们就可以根据需要使用不同的配置块来生成任意多的实例。

4. 我们创建一个Application\Form\Factory的实例,然后我们开始在配置数组中循环。

public static function generate(array $config)
{
  $form = new self();
  foreach ($config as $key => $p) {

5. 接下来,我们检查Application\Form\Generic类的构造函数中是否有可选的参数。

6. 现在所有的构造函数参数都到位了,我们可以创建表单元素实例,然后将其存储在$elements中。

7. 接下来,我们将注意力转移到选项上。如果设置了选项参数,我们使用list()将数组值提取到变量中。然后我们使用switch()测试元素类型,并使用适当数量的参数运行setOptions()

8. 最后,我们返回表单对象,并结束该方法。

9. 理论上,此时,我们可以通过简单地迭代元素数组并运行render()方法,轻松地在视图逻辑中渲染表单。视图逻辑可能是这样的。

10. 最后,我们返回表单对象,并结束该方法。

11. 接下来,我们需要在Application\Form\Element下定义一个离散的Form类。

12. 回到Application\Form\Factory类,我们现在需要定义一个简单的方法来返回一个sprintf()包装器模式,作为输入的分装。举个例子,如果包装器是一个属性为class="test"div,我们将产生这样的模式。<div class="test">%s</div>。然后我们的内容将被sprintf()函数替换成%s

13. 最后,我们准备好定义一个方法来进行整体表单的渲染。我们为每一个表单行获取包装器sprintf()模式。然后我们在元素中循环,渲染每一个元素,并将输出包装在行模式中。接下来,我们生成一个Application\Form\Element\Form实例。然后,我们检索表单包装器sprintf()模式,并检查form_tag_inside_wrapper标志,它告诉我们是否需要将表单标签放在表单包装器内部或外部。

如何运行...

参考前面的代码,创建Application\Form\FactoryApplication\Form\Element\Form类。

接下来,你可以定义一个chap_06_form_factor.php调用脚本,设置自动加载和锚定新类。

接下来,使用第一个示例中定义的$wrappers数组来定义包装器。您也可以使用第二个示例中定义的$statusList数组。

看看是否有来自$_POST的任何状态输入。任何输入都将成为选定的键。否则,选定的键是默认的。

现在您可以定义整体的表单配置。名称和属性参数用于配置表单标签本身。另外两个参数代表表单级和行级包装器。最后,我们提供了一个 form_tag_inside_wrapper 标志,用于指示表单标签不应该出现在包装器(即<table> )内部。如果包装器是<div>,我们会将这个标志设置为TRUE

接下来,定义一个数组,该数组为工厂要创建的每个表单元素保存参数。数组键是表单元素的名称,必须是唯一的。

最后,一定要生成表格。

实际的显示逻辑非常简单,因为我们只需调用表单级别的render()方法。

下面是实际输出。

最后更新于