Zend2 - 如何转发其他模块控制器?

时间:2016-09-01 09:50:51

标签: php zend-framework2 zfcuser

控制器转发 - 是一个很棒的功能,我用它制作了widget构思。但默认情况下它不能调度非自身模块的控制器。要解决这个问题(并且还要完全避免控制器配置),我为控制器构造添加了abstaract_factory:

namespace Engine\Mvc\Controller;

use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class Autoloader implements AbstractFactoryInterface
{
    public function canCreateServiceWithName(ServiceLocatorInterface $locator, $name, $requestedName)
    {
        return true;
    }

    public function createServiceWithName(ServiceLocatorInterface $locator, $name, $requestedName)
    {
        $class = ucfirst(str_replace('/', '\\', $requestedName)).'Controller';
        if (!class_exists($class)){
            return false;
        }
        return new $class;
    }
}

/*In Module class*/
public function getControllerConfig()
    {
        return array(
            'abstract_factories' => array(
                'Engine\Mvc\Controller\Autoloader'
            ),
        );
    }

工作正常。但仅限于可调用的控制器 - 没有构造函数参数。当我尝试从模块嵌入控制器时,我无法更改(例如, ZfcUser ,与作曲家一起安装) - 它可能会失败,因为theese控制器可能具有非可调用的init:

/*in zfc-user/module.config.php */
'controllers' => array(
        'factories' => array(
            'zfcuser' => 'ZfcUser\Factory\Controller\UserControllerFactory',
        ),
    ),

/*factory for controller*/
class UserControllerFactory implements FactoryInterface
{
    /**
     * Create controller
     *
     * @param ControllerManager $serviceLocator
     * @return UserController
     */
    public function createService(ServiceLocatorInterface $controllerManager)
    {
        /* @var ServiceLocatorInterface $serviceLocator */
        $serviceLocator = $controllerManager->getServiceLocator();

        $userService = $serviceLocator->get('zfcuser_user_service');
        $registerForm = $serviceLocator->get('zfcuser_register_form');
        $loginForm = $serviceLocator->get('zfcuser_login_form');
        $options = $serviceLocator->get('zfcuser_module_options');

        $controller = new UserController($userService, $options, $registerForm, $loginForm);

        return $controller;
    }
}

module1 中的Froward看不到 ZfcUser 模块的UserControllerFactory,它尝试使用我的abstract_factory构造控制器,并给出错误,因为UserController需要所有参数

可以通过交换Zend\Mvc\Controller\Plugin\Service\ForwardFactory来解决 - 只需要使用“全局”ControllerManager构建转发。但我不确定,Zend2中存在“全局”ControllerManager

问题

  1. 是否有全局ControllerManager,如何从ServiceManager获取它?
  2. 使用控制器插件转发非自身模块控制器(通过非自我模块控制器配置构建控制器)的任何其他方式?

1 个答案:

答案 0 :(得分:0)

问题消失了,我是愚蠢的。 Forward可以访问所有控制器,也可以访问非自控制器。但是通过控制器伪(控制器管理器中的名称) - 而不是类名,例如我们有控制器定义:

/*in zfc-user/module.config.php - here we have 'zfcuser' as controller pseudo */
'controllers' => array(
        'factories' => array(
            'zfcuser' => 'ZfcUser\Factory\Controller\UserControllerFactory',
        ),
 ),

我们可以从任何模块转发此控制器:

$widgetLogin = $this->forward()->dispatch('zfcuser', ['action' => 'login']);

感谢。

UPD:

如果您只想使用类的名称,从正向访问控制器(使用相同名称的Engine \ Mvc \ Controller \ Autoloader来解决问题) - 您可以在模块中为非自控制器添加别名,例如:

/*in module.config.php of your module*/
'controllers' => [
    'abstract_factories' => [
        'Engine\Mvc\Controller\Autoloader'
    ],
    'aliases' => [
        'ZfcUser/Controller/User' => 'zfcuser'
    ]
]