如何在 Zend Framework 中的两个模块中重用和覆盖控制器操作


How do I reuse and override controller actions across two modules in Zend Framework

我有一个Zend Framework的模块化设置,目前只有2个模块:

web
mobile

设置如下:

applications
--modules
----**web**
------controllers
--------IndexController.php
-----------function indexAction(){.......}
-----------function pageAction(){......}
------models
--------Model.php
------views
--------scripts
----------index.phtml
----**mobile**
------controllers
--------IndexController.php
------views
--------scripts
----------index.phtml
我想通过在模块

IndexController重用indexAction()pageAction() web模块,在mobile模块的IndexController中实现代码重用,并在**mobile**模块中添加另一个方法paperAction(),该方法仅适用于mobile模块。有没有办法做到这一点,而无需将代码复制到模块web IndexController.php mobile模块中?

谢谢

根据哪种方法适合您的需求,您可以创建一个基本控制器,每个模型中的索引控制器将从中扩展。 在基本控制器中,定义要在两者之间共享的最小功能。

或者,通过让另一个模块控制器从中扩展,使其中一个模块控制器成为主控制器。

在第一个示例中,您将执行以下操作:

application/controllers/IndexBaseController.php

<?php
class IndexBaseController extends Zend_Controller_Action {
    public function indexAction() {
        // shared code for both modules' indexaction here...
    }
    public function pageAction() {
        // shared code for both modules' pageaction here...
    }
}

然后,从下面扩展两个模块控制器:

application/modules/web/controllers/IndexController.php

<?php
require_once APPLICATION_PATH . '/controllers/IndexBaseController.php';
class Web_IndexController extends IndexBaseController {
    // other actions here, this already contains indexAction and pageAction()
}

然后对mobile/controllers/IndexController.php执行相同的操作。

另一种选择是使其中一个控制器(Web或移动(成为另一个控制器扩展的控制器。 请参阅此答案 分享 zend 模块控制器以在另一个模块中使用,以获取有关如何执行此操作的示例。 它类似,您只需要正确的控制器文件,以便您可以从中扩展。

是的,您可以随时实例化控制器并调用其方法

$web_ctlr=new Web_IndexController();
$web_ctlr->indexAction();
$web_ctlr->pageAction();

但问题是你在操作中做了什么,因为这些操作是为了准备渲染。 所以我想你最终会有多个输出,特别是如果你在控制器构造函数中进行一些 html 渲染。如果您从可重用操作中返回有效数据,那么您现在应该没问题。但是我建议您查看zend部分概念并确定哪一个适合您的情况

实际上你唯一需要的是这个(确保你在application.ini中设置了controllerDirectory(:

<?php
class App_Controller_Action_Helper_RequestForward extends Zend_Controller_Action_Helper_Abstract
{
    /**
     * @return null
     */
    public function direct($moduleName)
    {
        //this is basically the application.ini parsed & saved in Zend Registry
        $config = Zend_Registry::get('config');
        $controllersPath = $config->resources->frontController->controllerDirectory->$moduleName;
        $dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
        return $dispatcher->setControllerDirectory($controllersPath)->dispatch($this->getRequest(), $this->getResponse());
    }
}

然后在另一个模块的控制器中:

public function editAccountAction()
{
    return $this->_helper->RequestForward('default');
}