我可以在控制器工厂内从 GET 读取输入吗?


Can I read input from GET inside a Controller Factory?

这个问题并没有明确地与 ZF2 有关,但我经常从 ZF2 中获取 ques 作为我的代码。 也就是说,我在控制器操作中看到的大多数 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内完成。 除非我能打破这种模式?

如果您只想应用依赖反转原则。应用 DSLID 首字母缩略词,只需要进行一些更改。

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 nterface (SOL ID( 来改进

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'));
    }
}
上述服务/控制者

及其工厂应向其服务经理/控制者

注册
$config = [
    'controllers' = [
        'factories' [
             'YourController' => 'YourControllerFactory',
        ],
    ],
    'service_manager' = [
        'factories' [
             'ProcessorFactory' => 'ProcessorFactoryFactory',
        ],
    ],
];

当请求被调度到您的控制器时,控制器管理器返回一个注入了处理器的您的控制器实例。它获得哪个处理器取决于请求(RouteMatch 中的一个参数(。