我刚开始使用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_AddMyapp_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;
}


我唯一的另一条建议是尝试遵循您认为最合乎逻辑的方法。您可能会发现很难找到确定的“最佳实践”,因为有很多不同的方法可以做到这一切。

07-25 23:07
查看更多