我可以在 Controller Factory 中读取来自 GET 的输入吗?
Can I read input from GET inside a Controller Factory?
这个问题不是明确关于 ZF2 的,但我经常从 ZF2 那里得到我的代码的问题。也就是说,我见过的大多数 ZF2 示例都在控制器操作中处理输入。
示例:
class YourController extends AbstractActionController
{
public function doStuffAction()
{
// ZF2's way to get input from $_GET variable
$product = $this->getEvent()->getRouteMatch()->getParam('product');
// Process
$processor = (new ProcessorFactory())->getProcessor($product);
$output = $processor->processInput($data);
}
}
现在,我 喜欢 将 Processor
注入我的控制器。不要像我上面那样在控制器内部创建它。但是由于 Processor
依赖于知道 $product
,它只能从 $_GET
获得,我看不到任何其他方式。
如果我想将 Processor
注入控制器,我必须将填充 $product
变量的行也移到控制器之外。
如何在不严重破坏 OOP、ZF2 和设计模式的情况下这样做?在我看来,任何与 $_GET
相关的事情都应该在 Controller
内完成,而不是在 ControllerFactory
内完成。除非我能打破这种模式?
如果你只是想应用依赖倒置原则。应用 SOLID 首字母缩略词的 D,只需稍作改动。
class YourController
{
/**
* @var ProcessorFactory
*/
protected $processorFactory;
public function __construct(ProcessorFactory $processorFactory)
{
$this->processorFactory = $processorFactory;
}
public function doStuffAction()
{
$product = $this->getEvent()->getRouteMatch()->getParam('product');
$processor = $this->processorFactory->getProcessor($product);
}
}
您可以通过输入 I 界面 (SOLID)
来改进
class YourController
{
/**
* @var ProcessorFactoryInterface
*/
protected $processorFactory;
public function __construct(ProcessorFactoryInterface $processorFactory)
{
$this->processorFactory = $processorFactory;
}
public function doStuffAction()
{
$product = $this->getEvent()->getRouteMatch()->getParam('product');
$processor = $this->processorFactory->getProcessor($product);
}
}
现在,如果您不想让您的控制器负责启动创建过程 (SOLID),您可以将它再拆分一些。
class YourController
{
/**
* @var ProcessorInterface
*/
protected $processor;
public function __construct(ProcessorInterface $processor)
{
$this->processor = $processor;
}
public function doStuffAction()
{
$processor = $this->processor;
}
}
class ControllerFactory
{
/**
* @var ProcessorFactory
*/
protected $processorFactory;
public function __construct(ProcessorFactory $processorFactory)
{
$this->processorFactory = $processorFactory;
}
public function create()
{
return new YourController($this->processorFactory->getProcessor());
}
}
class ProcessorFactory
{
/**
* @var RouteMatch
*/
protected $routeMatch;
public function __construct(RouteMatch $routeMatch)
{
$this->routeMatch = $routeMatch;
}
public function getProcessor()
{
$processor = $this->createProcessor();
// do stuff
return $processor;
}
protected function createProcessor()
{
$product = $this->routeMatch->getParam('product');
// create processor
return $processor;
}
}
以下代码将为您提供控制器。
$controllerFactory = new ControllerFactory(new ProcessorFactory(new RouteMatch()));
$yourController = $controllerFactory->create();
现在上面的代码是更通用的代码,不适用于 ZF2。一个好的举措是让 ZF2 的服务经理参与进来。
class YourController extends AbstractActionController
{
/**
* @var ProcessorInterface
*/
protected $processor;
public function __construct(ProcessorInterface $processor)
{
$this->processor = $processor;
}
public function doStuffAction()
{
$processor = $this->processor;
}
}
class YourControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $controllers)
{
$services = $controllers->getServiceLocator();
$processorFactory = $services->get('ProcessorFactory');
return new YourController($processorFactory->getProcessor());
}
}
class ProcessorFactory
{
/**
* @var RouteMatch
*/
protected $routeMatch;
public function __construct(RouteMatch $routeMatch)
{
$this->routeMatch = $routeMatch;
}
public function getProcessor()
{
$processor = $this->createProcessor();
// do stuff
return $processor;
}
protected function createProcessor()
{
$product = $this->routeMatch->getParam('product');
// create processor
return $processor;
}
}
class ProcessorFactoryFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $services)
{
return new ProcessorFactory($services->get('RouteMatch'));
}
}
以上 services/controllers 他们的工厂应该在 ServiceManager/ControllerManager
注册
$config = [
'controllers' = [
'factories' [
'YourController' => 'YourControllerFactory',
],
],
'service_manager' = [
'factories' [
'ProcessorFactory' => 'ProcessorFactoryFactory',
],
],
];
当请求分派到 YourController 时,ControllerManager returns 一个注入处理器的 YourController 实例。它获得哪个处理器取决于请求(RouteMatch 中的一个参数)。
这个问题不是明确关于 ZF2 的,但我经常从 ZF2 那里得到我的代码的问题。也就是说,我见过的大多数 ZF2 示例都在控制器操作中处理输入。
示例:
class YourController extends AbstractActionController
{
public function doStuffAction()
{
// ZF2's way to get input from $_GET variable
$product = $this->getEvent()->getRouteMatch()->getParam('product');
// Process
$processor = (new ProcessorFactory())->getProcessor($product);
$output = $processor->processInput($data);
}
}
现在,我 喜欢 将 Processor
注入我的控制器。不要像我上面那样在控制器内部创建它。但是由于 Processor
依赖于知道 $product
,它只能从 $_GET
获得,我看不到任何其他方式。
如果我想将 Processor
注入控制器,我必须将填充 $product
变量的行也移到控制器之外。
如何在不严重破坏 OOP、ZF2 和设计模式的情况下这样做?在我看来,任何与 $_GET
相关的事情都应该在 Controller
内完成,而不是在 ControllerFactory
内完成。除非我能打破这种模式?
如果你只是想应用依赖倒置原则。应用 SOLID 首字母缩略词的 D,只需稍作改动。
class YourController
{
/**
* @var ProcessorFactory
*/
protected $processorFactory;
public function __construct(ProcessorFactory $processorFactory)
{
$this->processorFactory = $processorFactory;
}
public function doStuffAction()
{
$product = $this->getEvent()->getRouteMatch()->getParam('product');
$processor = $this->processorFactory->getProcessor($product);
}
}
您可以通过输入 I 界面 (SOLID)
来改进class YourController
{
/**
* @var ProcessorFactoryInterface
*/
protected $processorFactory;
public function __construct(ProcessorFactoryInterface $processorFactory)
{
$this->processorFactory = $processorFactory;
}
public function doStuffAction()
{
$product = $this->getEvent()->getRouteMatch()->getParam('product');
$processor = $this->processorFactory->getProcessor($product);
}
}
现在,如果您不想让您的控制器负责启动创建过程 (SOLID),您可以将它再拆分一些。
class YourController
{
/**
* @var ProcessorInterface
*/
protected $processor;
public function __construct(ProcessorInterface $processor)
{
$this->processor = $processor;
}
public function doStuffAction()
{
$processor = $this->processor;
}
}
class ControllerFactory
{
/**
* @var ProcessorFactory
*/
protected $processorFactory;
public function __construct(ProcessorFactory $processorFactory)
{
$this->processorFactory = $processorFactory;
}
public function create()
{
return new YourController($this->processorFactory->getProcessor());
}
}
class ProcessorFactory
{
/**
* @var RouteMatch
*/
protected $routeMatch;
public function __construct(RouteMatch $routeMatch)
{
$this->routeMatch = $routeMatch;
}
public function getProcessor()
{
$processor = $this->createProcessor();
// do stuff
return $processor;
}
protected function createProcessor()
{
$product = $this->routeMatch->getParam('product');
// create processor
return $processor;
}
}
以下代码将为您提供控制器。
$controllerFactory = new ControllerFactory(new ProcessorFactory(new RouteMatch()));
$yourController = $controllerFactory->create();
现在上面的代码是更通用的代码,不适用于 ZF2。一个好的举措是让 ZF2 的服务经理参与进来。
class YourController extends AbstractActionController
{
/**
* @var ProcessorInterface
*/
protected $processor;
public function __construct(ProcessorInterface $processor)
{
$this->processor = $processor;
}
public function doStuffAction()
{
$processor = $this->processor;
}
}
class YourControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $controllers)
{
$services = $controllers->getServiceLocator();
$processorFactory = $services->get('ProcessorFactory');
return new YourController($processorFactory->getProcessor());
}
}
class ProcessorFactory
{
/**
* @var RouteMatch
*/
protected $routeMatch;
public function __construct(RouteMatch $routeMatch)
{
$this->routeMatch = $routeMatch;
}
public function getProcessor()
{
$processor = $this->createProcessor();
// do stuff
return $processor;
}
protected function createProcessor()
{
$product = $this->routeMatch->getParam('product');
// create processor
return $processor;
}
}
class ProcessorFactoryFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $services)
{
return new ProcessorFactory($services->get('RouteMatch'));
}
}
以上 services/controllers 他们的工厂应该在 ServiceManager/ControllerManager
注册$config = [
'controllers' = [
'factories' [
'YourController' => 'YourControllerFactory',
],
],
'service_manager' = [
'factories' [
'ProcessorFactory' => 'ProcessorFactoryFactory',
],
],
];
当请求分派到 YourController 时,ControllerManager returns 一个注入处理器的 YourController 实例。它获得哪个处理器取决于请求(RouteMatch 中的一个参数)。