Zend Framework主要用于MVC。其中一个非常有用的组件是Zend_Form。
找到Zend_Form的位置有点麻烦。它是视图,模型或控制器的一部分,我应该赋予它哪些职责。
问题是,Zend_Form做了两件事:装饰并渲染表单并验证它。第一个是真实的视图任务,第二个是真正的模型任务。
现在最常见的用途似乎是让表单只与控制器交互,有效地将两个任务(渲染和验证)放到视图/控制器中。
Matthew Weier O'Phinney给出的另一个选项是将表单附加到模型,并在控制器中添加后面的视图选项。
所以,我很怀疑。我应该在MVC模式中放置Zend_Form以及如何使用它?
编辑目前为止的答案很好,谢谢!我将在它到期前一两个小时给予赏金,所以如果你有更多的想法,请给出答案!
答案 0 :(得分:5)
Zend_Form可以在不同的点上查看。它根本不能被视为一层MVC模式的一部分。
首先,Zend_Form使用装饰器和视图助手来渲染表单,此时它是视图层的一部分。 然后,Zend_Form执行模型作业过滤的一部分并验证内容。
我们知道Controller层从视图渲染输入并将其传递给模型。实际上,控制器层决定从模型层加载哪个资源,然后执行更正调用。
当您从控制器层调用Zend_Form时,您可以考虑调用一个模型资源来执行valitation和过滤操作,并确定这是否是有效输入。例如:
public function newAction()
{
$form = $this->getForm();
if($this->getRequest()->isPost())
{
$formData = $this->_request->getPost();
if($form->isValid($formData))
{
$Model = $this->getModel();
$id = $Model->insert($form->getValues());
}
}
$this->view->form = $form;
}
将表单绑定到模型可以被认为是一个很好的实践,因为当您执行过滤和验证操作时,您处于模型层。所以,正如马修提出的那样:
class Model_DbTable_Users extends Zend_Db_Table
{
protected $_name = 'users';
protected $_form;
public function getForm()
{
if(!$this->_form)
$this->_form = new Form_User();
return $this->_form;
}
public function add($data)
{
$form = $this->getForm();
if(!$form->isValid($data)) return false;
if($form->getValue('id'))
{
$id = (int) $form->getValue('id');
$this->update($form->getValues(), 'id =' . $id);
}
else
{
$id = $this->insert($form->getValues());
}
return $id;
}
}
从标准目录结构中我们可以看到Forms不在模型文件夹中,也不在视图文件夹中,因为Zend_Form是一个将许多资源和层绑定在一起的特定类。如果您查看Matthews帖子,您会发现这正是在视图脚本上设置操作URL并且表单与模型绑定时所说的内容。
最后,您可以分析您的背景并选择其中一种方法。
目前,我的选择是将表单与模型联系起来。看起来不错!对我来说很有意义。
答案 1 :(得分:2)
IMO,Zend_Form旨在戴上多个帽子。事实上,它是视图和模型之间的桥梁,带有来自控制器的巨大支撑梁。
不要将表单分配给模型,而是考虑将模型分配给表单。
在Model层中,您可以拥有一个getFormInputs方法,该方法可以返回输入数据所需的Elements。该模型并不关心将使用它的形式,它只是让任何想要它的人都可以使用它。
现在在表单层中,创建一个setupInputs方法,该方法将通过一组模型循环以获取所有输入。如果只有一个模型,请将输入添加到表单中。如果有多个模型,请创建子表单。
您的控制器将启动表单并将值传递回模型(请参阅Keyne的newAction方法)
答案 2 :(得分:1)
Zend_Form经常感觉像是一个奇怪的人。我想每个人的里程都各不相同。
最近,我的大多数管理界面都非常拖放AJAX-y,并且它们需要大量的html和javascript - 实际的表单元素很稀疏。因此,我选择避开Zend_Form的许多功能,并将其用作具有过滤功能的花式视图助手。我的所有验证都是在模型中的单独层上完成的。
我认为O'Phinney的想法也很有意义。在这里,他选择将表单视为域对象的一个组件 - 他可以在其中添加业务逻辑。这听起来很好,只要你小心保持表单的所有视图逻辑分开。正如他所指出的,它是关于使语义有意义的。不一定是硬性规定。