PHP面向对象的表单生成器


PHP object oriented form generator

我正在尝试创建一个面向对象的表单生成器。请记住,它只会被我们公司的少数人用来解决特定的问题。

我目前面临两个小问题。

创建元素的语法

我能采取的方法很少。

正在构造函数中设置所有内容。作为一个缺点,这可能导致不一致的构造函数使用

Input::create('text', 'name', array('maxlength' => 10));

将构造函数限制为键入并仅将最常用的属性作为方法公开(保留一个方法用于大规模属性设置)

Input::create('text')->name('name')->value('value')->attribute('max_length', 10);

通过为每个属性创建一个方法或使用__call魔术方法将每个属性公开为方法,这将导致IDE中不支持自动完成。即使现在,我也可以保留attribute方法。

Input::create()->type('text')->name('name')->value('value')->max_length(10)->id('id'); //etc.

目前,我认为第二种方法是最好的,因为它从两个世界都保留了"好"的东西。As仍然提供了一种对一些工作进行抽象的方法,因为例如方法required不仅会设置所需的属性,还会根据需要为验证对象标记该字段。

方法2和方法3的代码重复

由于存在每个元素都可以使用的属性,但也存在仅可由3或4个元素使用的属性(例如HTML5属性form)。

每个元素都可以从基本元素继承,基本元素具有针对每个元素通用的属性的方法(例如name)。部分可用的属性可以通过接口解决,但这会导致代码重复,因为它们不能包含方法体。

特性将是解决方案,但遗憾的是,我被困在PHP 5.3上,无法升级。这让我要么实现Mixin,要么实现Composition模式,这可能再次导致不支持自动完成。当使用第二种方法时,这将得到部分缓解。

所以我的实际问题是:

哪种方法最合适?(适用于最小的代码重复、可靠的代码重用和易于实现)

我意识到这很可能会产生基于观点的答案,所以如果真的发生了,我提前道歉。

我意识到这是一个老问题,但评论中有人提到了我创建的一个名为htmlgen的项目,该项目反映在packagist上。我最近发布了一个新的2.x版本,它使PHP中的HTML生成变得非常愉快,我在这里加入了一些支持。

use function htmlgen'html as h;
echo h('input', ['name'=>'catQty', 'value'=>500])

将呈现

<input name="catQty" value="500">

然而,就潜在的而言,这个例子几乎没有触及表面

h('#wrapper',
  h('h1.title', 'Hello, World'),
  h('p',
    h('comment', 'link to duckduckgo'),
    h('a', ['href'=>'https://duckduckgo'], 'search the internet')
  )
);

这是输出(实际输出没有空白)

<div id="wrapper">
  <h1 class="title">Hello, World</h1>
  <p>
    <!-- link to duckduckgo -->
    <a href="https://duckduckgo">search the internet</a>
  </p>
</div>

它在呈现数据集合时也非常方便

use function htmlgen'html as h;
use function htmlgen'map;
$links = [
  'home' => '/',
  'cats' => '/cats',
  'milk' => '/milk',
  'honey' => '/honey',
  'donuts' => '/donuts',
  'bees' => '/bees'
];
echo h('nav',
  h('ul',
    map($links, function($href, $text) { return
      h('li',
        h('a', ['href'=>$href], $text)
      );
    })
  )
);

将输出(同样,空白仅用于显示)

<nav>
  <ul>
    <li><a href="/">home</a></li>
    <li><a href="/cats">cats</a></li>
    <li><a href="/milk">milk</a></li>
    <li><a href="/honey">honey</a></li>
    <li><a href="/donuts">donuts</a></li>
    <li><a href="/bees">bees</a></li>
  </ul>
</nav>

这都是100%的PHP,没有自定义的、专有的有趣的业务。它表现力很强,适合于伟大的作品。您可以将模板分解为易于重用的函数或require调用。

IMO我会选择第二个选项。可能是因为它让我想起了jQuery。

Input::create('text')->name('name')->value('value')->attribute('max_length', 10);

在接口类"FormElements"中定义更通用的字段,如"name"、"value"、"attribute",并在类"Input"、"Select"等中实现/扩展。

尽管我个人更喜欢第二种选择。。用外星人保罗的话说:"有时候你只需要掷骰子"。