Могу ли я прочитать ввод из GET внутри фабрики контроллеров?

Этот вопрос явно не касается 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 переменная вне контроллера.

Как я могу сделать это, не нарушая ООП, ZF2, шаблонов дизайна? Как и у меня сложилось впечатление, что что-либо делать с $_GET должно быть сделано внутри Controllerа не внутри ControllerFactory, Разве возможно я смогу сломать этот паттерн?

0

Решение

Если вы просто хотите применить принцип инверсии зависимости. Применяя D из SOLID акроним, только несколько изменений необходимы.

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);
}
}

Вы могли бы улучшить, напечатав на яnterface (SOLяD)

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'));
}
}

Выше сервисы / контроллеры и их фабрики должны быть зарегистрированы в их ServiceManager / ControllerManager

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

Когда запрос отправляется в YourController, ControllerManager возвращает экземпляр YourController с введенным процессором. Какой процессор он получит, зависит от запроса (параметр внутри RouteMatch).

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]