我可以在构造函数中使用带参数的ZF3 MVC Framework Controller吗?

时间:2017-02-27 12:13:22

标签: zend-framework-mvc zend-framework3

我有一个Zend Framework 3 MVC应用程序,带有两个端点的控制器。两者都需要访问同一个类。看起来这样做的最好方法是将这个类的实例作为控制器类的属性,如下所示:

class IndexController extends AbstractActionController
{
    /**
     * var Utility $utility
     */
    protected $utility;


    public function __construct(Utility $utility) 
    {
        $this->utility = $utility;
    }

    public function indexAction()
    {
        $this->utility->doA('param1');
        return new ViewModel();
    }

    public function otherAction()
    {
        $results = $this->utility->validateRequest($this->request);
        if ($results) 
        {
            return new ViewModel();
        } 
        else 
        {
            throw new Exception('Invalid request');
        }
    }
}

但是,我不知道如何将参数传递给构造函数,因为我不知道Zend Framework在哪里“制作”它。

1 个答案:

答案 0 :(得分:1)

Zend Framework使用名为Dependency Injection的概念。这基于SOLID中的D,dependency inversion。除了理论之外,您还需要在modules.config.php中为控制器创建自定义工厂。您还需要为class calld Utility创建一个工厂。

首先,您可能使用类似于composer create-project -sdev zendframework/skeleton-application的命令创建项目。如果您这样做,您可能没有最新版本的Service Manager。查看文件vendor/bin/generate-factory-for-class是否存在。如果没有,请执行composer update zendframework/zend-servicemanager将其添加到那里。

现在让我们为实用程序类创建一个工厂。让我们假设它在module/Application/src/Service/Utility.php中并且具有名称空间Application\Service。您只需输入vendor/bin/generate-factory-for-class Application\\Service\\Utility > module/Application/src/Service/UtilityFactory.php即可。如果查看该文件,您可以看到:

public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
    return new Utility();
}

现在让我们为vendor/bin/generate-factory-for-class Application\\Controller\\IndexController > module/Application/src/Controller/IndexControllerFactory.php的控制器做同样的事情。打开这家工厂,看看它有点复杂。

public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
    return new IndexController($container->get(\Application\Service\Utility::class));
}

$container是您的依赖注入容器。它在调用时在这些工厂中执行__invoke命令。

还有一件事要做。你需要编辑你的module.config.php。替换

'controllers' => [
    'factories' => [
        Controller\IndexController::class => InvokableFactory::class,
    ],
],

'controllers' => [
    'factories' => [
        Controller\IndexController::class => Controller\IndexControllerFactory::class,
    ],
],

现在将以下部分添加到配置中:

'service_manager' => [
    'factories' => [
        Service\Utility::class => InvokableFactory::class,
    ],
],

然后你的控制器应该工作。