重构Zend_Controller_Action

时间:2011-04-27 20:59:26

标签: php zend-framework frameworks

我一直在使用ZendFramework和Doctrine2进行一个项目,并注意到我的动作控制器的问题不是很“干”。鉴于以下示例,在我的所有控制器中几乎完全相同,这将是分解重复的最佳方法。我认为baseController是迄今为止最简单的,但似乎扩展Zend_Controller_Action是不受欢迎的。我倾向于另外两个选项是创建一个动作助手或控制器插件(但控制器插件对我来说仍然是一个模糊的概念)。
所以我的问题是,最好的方法是什么?为什么?

class Job_JobController extends Zend_Controller_Action
{

   protected $_service;

   public function init()
   {
        $ajaxContext = $this->_helper->getHelper('AjaxContext');
        $ajaxContext->addActionContext('create', 'html')
                    ->addActionContext('update', 'html')
                    ->addActionContext('view', 'html')
                    ->addActionContext('delete', 'html')
                    ->addActionContext('message', 'html')
                    ->initContext();
        $this->_service = $this->_helper->service('job');
    }

    public function indexAction()
    {
         $this->_forward('list');
    }

    public function listAction()
    {
        $grid = $this->_service->getGrid();
        $this->view->list = $grid->render();      
    }

    public function createAction()
    {
        $request = $this->getRequest();
        $formMediator = $this->_service->getFormMediator();

        if ($request->isPost() && $formMediator->isValid($request->getPost()))
        {
            $this->_service->saveEntity($formMediator->transfer());
            $this->_helper->flashMessenger->addMessage(array('statusCode' => 'Create::Success'));
            $this->_forward('message');
        }

        $this->view->entity = $formMediator->getForm();       
    }

    public function updateAction()
    {
        $request = $this->getRequest();
        $formMediator = $this->_service->getFormMediator();
        $entity = $this->_service->findEntity($request->getParam('id'));

        if ($request->isPost() && $formMediator->isValid($request->getPost()))
        {
            $this->_service->saveEntity($formMediator->transfer($entity));
            $this->_helper->flashMessenger->addMessage(array('statusCode' => 'Update::Success'));
            $this->_forward('message');
        } 
        else
        {
            $formMediator->populate($entity);
        }

        $this->view->entity = $formMediator->getForm();
    }


    public function viewAction()
    {
        $request = $this->getRequest();
        $this->view->entity = $this->_service->getEntity($request->getParam('id'));
    }

    public function deleteAction()
    {
        $request = $this->getRequest();
        $id = $request->getParam('id');

        if ($this->getRequest()->isPost())
        {
            $this->_service->delete($request->getParam('id'));
            $this->_helper->flashMessenger->addMessage(array('statusCode' => 'Delete::Success'));
            $this->_forward('message'); 
         }

         $this->view->deleteId = $id;
    }

    public function messageAction()
    {
         $messages = array_merge((array)$this->_helper->flashMessenger->getMessages(), 
                     (array)$this->_helper->flashMessenger->getCurrentMessages());
         $this->view->messages = $messages;
    }

}

3 个答案:

答案 0 :(得分:2)

扩展Zend_Controller_Action没有任何问题。对于我们的软件,我们对其进行了扩展,并使用preDispatch()函数验证用户是否已经过身份验证,如果没有,则显示登录屏幕。现在我们所有的控制器都扩展了那个,我们不需要为我们所有的页面做任何需要登录的事情。

答案 1 :(得分:1)

不是真正的答案,但我认为两种方式(扩展Zend_Controller_Action或Action-Helper)都是您正在寻找的解决方案。我没有看到任何理由,为什么抽象控制器有点......丑陋(?)。它是OOP的工作方式。

答案 2 :(得分:1)

我认为抽象控制器应该没问题,虽然我有时觉得它有点不优雅,因为测试抽象类的行为很棘手。

看过这段代码,你可以做的一件事是Replace Temp with Query。除了保存一些微不足道的输入(有时打字甚至比你需要的更多)之外,你正在进行临时变量赋值。有时值得键入一些额外的字符,以减少方法中有助于重构的临时/局部变量的数量。