我正在尝试创建面向对象的表单生成器。请记住,只有我们公司的少数人才能使用它来解决具体问题。
我目前面临两个小问题。
创建元素的语法
我可以采取的方法很少。
在构造函数中设置所有内容。作为缺点,这可能导致构造函数使用不一致
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.
目前,我认为第二种方法是最好的方法,因为它保留了两个世界的“好”东西。仍然提供了一种抽象一些工作的方法,例如,方法required
不仅会设置必需的属性,还会根据需要将此字段标记为验证对象。
使用方法2和3重复代码
由于每个元素都可以使用属性,但也只有3或4个元素可以使用的属性,例如HTML5属性form
。
每个元素都可以从base元素继承,该元素具有每个元素通用的属性方法(例如name
)。部分可用的属性可以通过接口解决,但这会导致代码重复,因为它们不能包含方法体。
Traits将是解决方案,但遗憾的是,我陷入了PHP 5.3无法升级。这使我无法实现Mixin或Composition模式,这可能导致没有自动完成支持。使用第二种方法时,这将部分减轻。
所以我的实际问题是:
哪种方法最适合? (适用于最小代码重复,固体代码重用和易于实现)
我意识到这可能会很好地产生基于意见的答案,所以如果有的话,我会事先道歉。
答案 0 :(得分:1)
我意识到这是一个老问题,但评论中有人提到了我创建的名为 naomik/htmlgen 的项目。我在这里得到了一些支持,因为我最近发布了一个新版本2.x,它使PHP的生成非常愉快。
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 project'),
h('a', ['href'=>'https://github.com/naomik/htmlgen'], 'See htmlgen on Github')
)
);
这里是输出(实际输出没有空格)
<div id="wrapper">
<h1 class="title">Hello, World</h1>
<p>
<!-- link to project -->
<a href="https://github.com/naomik/htmlgen">See htmlgen on Github</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
来电。
查看examples了解更多精彩提示
答案 1 :(得分:0)
IMO我会选择第二种选择。可能是因为它让我想起了jQuery。
Input::create('text')->name('name')->value('value')->attribute('max_length', 10);
在接口类'FormElements'中定义更多通用字段,如'name','value','attribute',并在类'Input','Select'等中实现/扩展它。
虽然我个人更喜欢第二种选择..用外星人保罗的话来说“有时候你只需掷骰子”。