我可以在构造函数中使用带参数的 ZF3 MVC 框架控制器吗?
Can I have a ZF3 MVC Framework Controller with parameters in the constructor?
我有一个带有两个端点的控制器的 Zend Framework 3 MVC 应用程序。两者都需要访问相同的 class。看起来最好的方法是将此 class 的实例作为控制器 class 的 属性 的实例,如下所示:
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 "makes" 它在哪里。
Zend Framework 使用了一个名为 Dependency Injection. This is based on the D in SOLID, dependency inversion 的概念。除了理论,您需要在 modules.config.php 中为您的控制器创建一个自定义工厂。您还需要为 class calld Utility 创建一个工厂。
所以首先,您可能使用类似于 composer create-project -sdev zendframework/skeleton-application
的命令创建了您的项目。如果这样做,您可能没有最新版本的服务管理器。查看文件 vendor/bin/generate-factory-for-class
是否存在。如果没有,执行composer update zendframework/zend-servicemanager
将其添加到那里。
现在让我们为实用程序创建一个工厂 class。让我们假设它在 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,
],
],
那么你的控制器应该可以工作了。
我有一个带有两个端点的控制器的 Zend Framework 3 MVC 应用程序。两者都需要访问相同的 class。看起来最好的方法是将此 class 的实例作为控制器 class 的 属性 的实例,如下所示:
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 "makes" 它在哪里。
Zend Framework 使用了一个名为 Dependency Injection. This is based on the D in SOLID, dependency inversion 的概念。除了理论,您需要在 modules.config.php 中为您的控制器创建一个自定义工厂。您还需要为 class calld Utility 创建一个工厂。
所以首先,您可能使用类似于 composer create-project -sdev zendframework/skeleton-application
的命令创建了您的项目。如果这样做,您可能没有最新版本的服务管理器。查看文件 vendor/bin/generate-factory-for-class
是否存在。如果没有,执行composer update zendframework/zend-servicemanager
将其添加到那里。
现在让我们为实用程序创建一个工厂 class。让我们假设它在 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,
],
],
那么你的控制器应该可以工作了。