我刚开始使用Zend Framework,所以我对结构有很多疑问。
我希望我能正确解释,这很困难。
好的,我已经完成了快速入门教程,并决定为我的第一个项目使用类似的结构。
所以我有一个数据映射器,一个模型和数据库表文件。
我创建了一个表单,可以在其中输入一些信息(项目)并上传图像。
我有2个Datamapper(项目和图像)以及2个模型。我有一个项目控制器,该控制器跳入了ItemMapper。在Datamapper中,我有一个save方法。请看下面:
public function save(Application_Model_Item $item)
{
$data = array(
'item_title' => $item->getItemTitle(),
'item_description' => $item->getItemDescription(),
);
$this->getDbTable()->insert($data);
// Add Image Information ($imageData is Session Data)
$table = new Application_Model_DbTable_Image();
foreach ($imageData as $fileData)
{
$image = new Application_Model_Image($fileData);
$data = array(
'image_newname' => $image->getNewImageName(),
'image_thumbname' => $image->getImageThumbName(),
);
$table->insert($data);
}
现在我有问题。
我的模型中有Getter和Setter。项目数据库表中的所有内容都应属于1种模型吗?意味着有关图像的所有内容都应归入图像模型,因为它位于不同的数据库表中?
将有关图像的信息保存在项目映射器中是否正确?我应该在ImageMapper中没有save()方法并将其保存在其中吗?如果是这样,我如何从项目映射器跳到图像映射器?还是我首先要完成有关Item的所有工作,将ID返回给Controller,然后再从Controller调用ImageMapper?
我读了一些有关“胖模型瘦控制器”的文章。我一直都这样,但是我注意到我的Controller仅仅通过将Form放在一起就变得很胖。我有大约5个下拉列表字段,这些字段取决于下拉列表。当看到复制代码时,我决定将其添加到单独的函数中。所以我有一个县的下拉菜单。我在控制器中也写了一个Function,它看起来像这样:
public function getCounties ()
{
// List of Counties does not exist in Cache, read from DB
if(!$CountyList = $this->getFromCache('counties')){
$geolocationMapper = new Application_Model_GeolocationMapper();
$CountyDropdown = $geolocationMapper->createCountyDropdown();
// Save DB Result in Cache
$this->addToCache ('counties',$CountyDropdown);
return $CountyDropdown;
}
else{
// Return Country List from Cache
return $this->getFromCache('counties');
}
}
在我的添加函数中,我使用
//将地理信息分配给表单
$CountyList = $this->getCounties();
$form->getElement('county')->setMultiOptions($CountyList);
编辑功能比
$CountyList = $this->getCounties();
$form->getElement('county')->setMultiOptions($CountyList)->setValue($activeCounty)
所有诸如getCounties()之类的函数都保留在Controller中,还是应该将其移至GeolocationMapper?如果是这样,该如何调用?
应该在某些函数中创建Form,以便我只调用诸如createForm()之类的东西吗?我确实有很多重复项(添加和编辑功能),而且Stuff来自数据库或Form无效,它来自具有setValue的Cache。使用可靠的下拉菜单时,它只会累加起来。
我知道这有很多问题,但是我觉得它会变得非常混乱,作为学习者,您会感到高兴,但我也想以适当的方式来构造它。我希望这一切都有道理。
也许有些人可以使用一些提示。非常感谢您的提前帮助。
最佳答案
这里有很多问题,大多数答案很大程度上取决于个人喜好。避免这种警告:
项目数据库表中的所有内容都应属于1种模型吗?
我会说是的,尽管总的来说,请尝试从模型而不是数据库结构的角度考虑它。因此,所有“ item”数据都放在Item模型中,因为所有数据都存储在一个数据库表中,这一事实是无关紧要的,因为映射器会处理从一个到另一个的转换。
将有关图像的信息保存在项目映射器中是否正确?
目前尚不清楚$ imageData在您的示例中来自何处,但我想说如果有要保存的图像数据,则Item映射器应调用Image映射器,例如:
public function save(Application_Model_Item $item)
{
$data = array(
'item_title' => $item->getItemTitle(),
'item_description' => $item->getItemDescription(),
);
$this->getDbTable()->insert($data);
// save image data if present
if (isset($item->image)) {
$imageMapper = new Yourapp_Mapper_Image();
$imageMapper->save($item->image);
}
return true;
}
[应该]像getCounties()这样的所有函数都保留在Controller中,还是应该将其移至GeolocationMapper?如果是这样,该如何调用?
我看不出将这些功能包含在控制器中的任何原因。根据您对
Zend_Form
组件的适应程度,一种方法可能是编写扩展Yourapp_Form_Element_Counties
的自定义Zend_Form_Element_Select
类。然后,将逻辑从getCounties函数移到此类中,因此form元素本身负责填充其提供的选项。例如。:class Yourapp_Form_Element_Counties extends Zend_Form_Element_Select
{
public function getMultiOptions()
{
// load counties here and return an array in the format key -> value
}
}
如果您有很多与位置相关的表单元素,则另一种方法可能是创建GeoLocation Service类,该类具有用于县,市等的函数,该函数返回选项。
应该在某些函数中创建表格,这样我只会调用诸如createForm()之类的东西
除了填充选择选项外,尚不清楚您在控制器中正在执行多少表单工作,因此很难回答这一问题。使用Zend_Form时,通常遵循以下原则:
每个表单都有自己的类,扩展了Zend_Form(或Zend_Dojo_Form),该类存在于应用程序/表单中,名为Myapp_Form_ *。
每个表单类都在init()方法中设置其元素(为此,Zend_Form的构造方法会自动调用该方法)。
如果发现需要在不同操作(例如添加和编辑操作)中对同一表单进行细微改动,则为该表单创建一个抽象基类(例如
Myapp_Form_Post_Base
),该基类定义元素,然后创建特定于动作的类扩展了它:Myapp_Form_Post_Add
,Myapp_Form_Post_Edit
等。这些类在其自己的init()方法中对基本表单进行了所需的任何更改。我的动作如下所示:
public function editAction()
{
$form = new Myapp_Form_Post_Edit();
if ($this->_request->isPost()) {
if ($form->isValid($this->_request->getPost()) {
// save data, set flash messge and redirect
}
}
$this->view->form = $form;
}
我唯一的另一条建议是尝试遵循您认为最合乎逻辑的方法。您可能会发现很难找到确定的“最佳实践”,因为有很多不同的方法可以做到这一切。