Zend framework 数据映射器、控制器和模型的Zend框架结构

Zend framework 数据映射器、控制器和模型的Zend框架结构,zend-framework,Zend Framework,我刚刚开始使用Zend框架,所以我对它的结构有很多疑问。 我希望我能解释清楚,这很难 好的,我已经完成了快速入门教程,并决定在我的第一个项目中使用类似的结构 所以我有一个数据映射器,一个模型和数据库表文件 我已经创建了一个表单,在这里我可以输入一些信息(项目)并上传图像 我有2个数据映射器(项目和图像)以及2个模型。我有一个项目控制器,它跳入项目映射器。在Datamapper中,我有一个save方法。请参阅下文: public function save(Application_Model_I

我刚刚开始使用Zend框架,所以我对它的结构有很多疑问。 我希望我能解释清楚,这很难

好的,我已经完成了快速入门教程,并决定在我的第一个项目中使用类似的结构

所以我有一个数据映射器,一个模型和数据库表文件

我已经创建了一个表单,在这里我可以输入一些信息(项目)并上传图像

我有2个数据映射器(项目和图像)以及2个模型。我有一个项目控制器,它跳入项目映射器。在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()方法并将其保存在那里吗?如果是,如何从项目映射器跳到图像映射器?或者我会先完成关于项目的所有工作,将ID返回给控制器,然后从控制器调用ImageMapper吗
  • 我读了一些关于“胖模型瘦控制器”的文章。我的had里一直都有这个,但我注意到我的控制器在把表单放在一起时变得非常胖。我有大约5个下拉字段,它们取决于下拉列表。当我看到我正在复制代码时,我决定将其添加到一个单独的函数中。所以f.e.我有一个县的下拉列表。我写了一个函数,它也在我的控制器中,所以它看起来像这样:

    public function getCounties ()
    
    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;
    }
    
    {

    }

  • 在我的Add函数中,我使用

    //将地理信息分配到表单

    $CountyList = $this->getCounties();               
    $form->getElement('county')->setMultiOptions($CountyList);   
    
    编辑功能比

    $CountyList = $this->getCounties();
    $form->getElement('county')->setMultiOptions($CountyList)->setValue($activeCounty)
    
    像getCountries()这样的所有函数都保留在控制器中,还是应该将其移动到GeolocationMapper?如果是这样的话,那该怎么说呢

  • 是否应该在某个函数中创建表单,以便我只调用createForm()之类的函数?我真的有很多重复(添加和编辑功能),但来自数据库或表单的内容无效,它来自具有设置值的缓存。当使用可靠的下拉列表时,它只是加起来 我知道这是很多问题,但我感觉它变得非常混乱,作为一个学习者,当它工作时你会很高兴,但我也希望以一种适当的方式来组织它。我希望这一切都有意义


    也许你们有些人有一些酒我可以用。非常感谢您的帮助。

    这里有很多问题,大部分答案主要取决于个人喜好。有了这个警告:

    项目数据库表中的所有内容都应该在1模型中吗

    我会说是的,尽管一般来说,试着从模型而不是数据库结构的角度来考虑它。所以所有的“item”数据都在item模型中——这些数据都存储在一个数据库表中这一事实是不相关的,因为映射器处理从一个到另一个的转换

    在项目映射器中保存有关图像的信息是否正确

    在您的示例中,$imageData从何而来还不清楚,但我想说,如果有图像数据要保存,项目映射器应该调用图像映射器,例如:

    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;
    }
    
    [应该]像getCountries()这样的所有函数都留在控制器中,还是应该将其移动到GeolocationMapper?如果是这样的话,那该怎么说呢

    我看不出有任何理由将这些函数放在控制器中。根据您对
    Zend\u表单
    组件的熟悉程度,一种方法可能是编写一个扩展
    Zend\u表单元素选择
    的自定义
    Yourapp\u表单元素
    类。然后,将逻辑从getCountries函数移动到this类中,因此表单元素本身负责填充它显示的选项。例如:

    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
        }
    }
    
    如果您有许多与位置相关的表单元素,另一种方法可能是创建一个地理位置服务类,该类具有用于县、市等的函数,该函数返回选项

    是否应该在某个函数中创建表单,以便我只调用类似createForm()的内容

    除了填充选择选项之外,还不清楚您在控制器中已经做了多少表单工作,所以很难回答这个问题。以下是我在使用Zend_表单时通常遵循的原则:

    • 每个表单都有自己的类,扩展Zend_表单(或Zend_Dojo_表单),它存在于应用程序/表单中,名为Myapp_表单_*
    • 每个form类都在init()方法中设置其元素(Zend_form的构造函数为此自动调用该方法)
    • 如果我发现在不同的操作中(例如,在添加和编辑操作中)需要对同一表单进行细微的更改,我会为表单创建一个抽象基类(例如,定义元素的
      Myapp\u form\u Post\u base
      ),然后创建扩展它的特定于操作的类:
      Myapp\u form\u Post\u add
      Myapp\u表单\u发布\u编辑
      等等。这些类在自己的init()方法中对基窗体进行所需的任何更改
    我的动作看起来像这样:

    public function getCounties ()
    
    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;
    }
    

    我唯一的另一条建议是尝试并遵循你认为最符合逻辑的方法。你可能会发现很难找到很多这样的东西的明确的“最佳实践”,因为有很多不同的方法可以做到这一点。

    我尽可能地遵循你的想法,所以所有对县、镇和邮政编码的调用都在地理位置映射器中,图像数据的保存在ImageMapper中

    你问我现在如何创建我的表单,这里是一个来自我的init()的例子,用于县等的表单

      // Create Dropdown for Counties          
        $county = new Zend_Form_Element_Select('county');      
        $county->setLabel('Select a County')
               ->setRegisterInArrayValidator(false) 
           ->setDecorators(array(
            'ViewHelper',
            'Errors',
                  array('Description', 
                          array('tag' => 'p', 'class'=>'description')),         
                        'Label',
                  array('HtmlTag',
                  array('tag'=>'li','class'=>'county'))                 
                 ))  
               ->setRequired(false);
    
        // Create Dropdown for Town
        $town = new Zend_Form_Element_Select('town');
        $town->setRegisterInArrayValidator(false)
             ->setDecorators(array(
                                'ViewHelper',
                                'Errors',
                                array('Description', array('tag' => 'p', 'class' => 'description')),
                                'Label',
                                array('HtmlTag',array('tag'=>'li','class'=>'town'))
                                ));  
    
    
        // Create Dropdown for Postcode
        $postcode = new Zend_Form_Element_Select('postcode');
        $postcode->setRegisterInArrayValidator(false)
                 ->setDecorators(array(
                                'ViewHelper',
                                'Errors',
                                array('Description', array('tag' => 'p', 'class' => 'description')),
                                'Label',
                                array('HtmlTag',array('tag'=>'li','class'=>'postcode'))
                                )) 
                 ->setRegisterInArrayValidator(false);
    
    在我的控制器中,我获取元素并填充它们:

    $geolocationMapper = new Application_Model_GeolocationMapper();
    $CountyOptions = $geolocationMapper->createCountyDropdown();
    $form->getElement('county')->setMultiOptions($CountyOptions);
    
    <