Содержание


Доступные Контроллеры


Available Controllers, MVC, ЗФ2, Zend Framework 2, ZF2, ру, ru




В MVC системе ZF2 контроллеры – это объекты, реализующие интерфейс Zend\Stdlib\DispatchableInterface. Этот интерфейс описывает всего один метод:

use Zend\Stdlib\DispatchableInterface;
use Zend\Stdlib\RequestInterface as Request;
use Zend\Stdlib\ResponseInterface as Response;
 
class Foo implements DispatchableInterface
{
    public function dispatch(Request $request, Response $response = null)
    {
        // ... do something, and preferably return a Response ...
    }
}

Хотя такая модель и достаточно проста, Вы врядли захотите реализовать логику диспетчеризации для каждого контроллера (если конечно нет ситуации для создания специфической логики обработки нескольких взаимосвязанных запросов).

 

Так же в MVC определены несколько дополнительных интерфейсов, которые при своей реализации позволяют обеспечивать контроллерам дополнительный функционал.

 

Общие интерфейсы, используемые с контроллерами

 


InjectApplicationEvent

 

Zend\Mvc\InjectApplicationEventInterface сообщает экземпляру приложения, что необходимо инъецировать MvcEvent непосредственно в контроллер. Как это может быть полезно для Вас?

 

Напомним, что MvcEventсостоит из набора объектов: Request, Response, router, routematches (RouteMatch), а также «result» (результат) диспетчеризации.

 

Контроллер, в который инъецирован MvcEvent может использовать все его составляющие. Пример:

$matches = $this->getEvent()->getRouteMatch();
$id      = $matches->getParam('id', false);
if (!$id) {
    $response = $this->getResponse();
    $response->setStatusCode(500);
    $this->getEvent()->setResult('Invalid identifier; cannot complete request');
    return;
}

InjectApplicationEventInterface определяет всего два метода:

public function setEvent(Zend\EventManager\EventInterface $event);
public function getEvent();


ServiceLocatorAware

 

В большинстве случаев, Вы будете определять свои контроллеры таким образом, что зависимости будут внедряться с помощью ServiceManager приложения, или же используя аргументы конструктора или методы «setter».

 

Однако, при необходимости Вы можете использовать объекты в контроллере, которые будут валидны только для определенных частей кода. Как пример: использование форм, пагинации, навигации и т.д. Возможно, у Вас возникнет мысль, что нет необходимости инъецировать эти объекты каждый раз в контроллер при его использовании.

ServiceLocatorAwareInterface сообщает ServiceManager’у, что он должен инъецировать сам себя в контроллер. Определяет два метода:

use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
 
public function setServiceLocator(ServiceLocatorInterface $serviceLocator);
public function getServiceLocator();


EventManagerAware

 

Иногда удобно внедряться в рабочий процесс контроллера без необходимости его расширять или жестко привязываться к его поведению. Для осуществления этой возможности в фреймворке используется EventManager.

 

Можно использовать ServiceManager для инъекцирования EventManager с помощью реализации интерфейса EventManagerAwareInterface.

 

Для начала необходимо определить два метода. Первый -  «setter», устанавливает любые идентификаторы EventManager для обеспечения прослушивания событий, а второй – «getter», который просто возвращает  экземпляр EventManager.

use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerInterface;
 
public function setEventManager(EventManagerInterface $events);
public function getEventManager();


Плагины контроллера

 

Написание кода, который можно использовать повторно является одной из целей разработчиков, так как это является довольно удобным. Однако, это является доволно трудной задачей в общих и абстрактных системах.

 

В контроллерах, Вы будете сталкиваться с повторяющимся задачами. Например:

 

- Создание URL

- Перенаправление

- Установка и извлечение флэш-сообщений (сообщения сессий)

-  Вызов и диспетчеризация дополнительных контроллеров

 

Для этого используется реализация PluginManager. Zend\Mvc\Controller\PluginManager построен на основе Zend\ServiceManager\AbstractPluginManager. Для его использования Вам просто необходимо реализовать метод setPluginManager(PluginManager $plugins), а так же написать необходимый код, который будет использоваться по умолчанию.

use Zend\Mvc\Controller\PluginManager;
 
public function setPluginManager(PluginManager $plugins)
{
    $this->plugins = $plugins; 
    $this->plugins->setController($this);
 
    return $this;
}
 
public function getPluginManager()
{
    if (!$this->plugins) {
        $this->setPluginManager(new PluginManager());
    }
 
    return $this->plugins;
}
 
public function plugin($name, array $options = null)
{
    return $this->getPluginManager()->get($name, $options);
}




AbstractActionController

 

Реализация каждого из выше описанных интерфейсов достаточно обширна и Вам врядли захочется  часто все это использовать. Поэтому были созданы два абстрактных , базовых контроллера, которые можно расширять, приступая к работе.

 

Первыйэто  Zend\Mvc\Controller\AbstractActionController. Он реализует каждый из перечисленных интерфейсов и предполагает следующее:

 

- В объекте RouteMatch должен находиться параметр «action», созданный в прикрепленном MvcEvent. Если же такого нет, то используется метод notFoundAction().

- Параметр «action» преобразовывается в формат «camelCased» и добавляет слово «Action», создавая тем самым имя метода. Например: «foo» становится «fooAction», а «foo-bar» или «foo.bar», или «foo_bar» становится «fooBarAction». Затем контроллер проверяет, существует ли такой метод. Если нет – вызывается метод notFoundAction(), если да -  вызывается обнаруженный метод.

- Результат выполнения данного метода инъекцируется в свойство MvcEvent «result» (с помощью метода «setResult()», а доступно через метод «getResult()» ).

 

По сути, для карты маршрутов (routemapping) в AbstractActionController необходимы оба ключа «controller» и «action» для поиска совпадения.

 

Создание контроллеров действий является достаточно простым:

namespace Foo\Controller;
 
use Zend\Mvc\Controller\AbstractActionController;
 
class BarController extends AbstractActionController
{
    public function bazAction()
    {
        return array('title' => __METHOD__);
    }
 
    public function batAction()
    {
        return array('title' => __METHOD__);
    }
}

Интерфейсы

 

AbstractActionController реализует каждый из следующих интерфейсов:

- Zend\Stdlib\DispatchableInterface

- Zend\Mvc\InjectApplicationEventInterface

- Zend\ServiceManager\ServiceLocatorAwareInterface

- Zend\EventManager\EventManagerAwareInterface

 

Настроенный EventManager настроен на прослушивание :

- Zend\Stdlib\DispatchableInterface

- Zend\Mvc\Controller\AbstractActionController

 

Так же, если Вы расширите класс, то будет и прослушиваться класс-рассширение.

 



AbstractRestfulController

 

Второй абстрактный класс контроллер это Zend\Mvc\Controller\AbstractRestfulController. Он обеспечивает простую реализацию RESTful, которая просто отображает методы HTTP запросов на методы контроллеров, используя следующую матрицу:

 

- GET. Доступен через «get()» или «getList()», в зависимости от наличия или отсутствия параметра «id», который должен находиться в маршруте «route». Если присутствует -  то передается как аргумент в «get()». Иначе вызывается метод «getList()».  В первом случае необходимо обеспечить предоставление сущности с идентификатором, во втором -  список сущностей.

 

- POST. Доступен через метод «create()».  Должен передаваться аргумент «$data», обычно это супер глобальный массив $_POST. Данные используются для создания новой сущности (объекта), а HTTP ответ должен быть «201», а в Location header должно быть указан URI только что созданного объекта, в теле ответа  указано его представление. 

 

- PUT. Доступен через метод «update()». Требует, что бы параметр «id» был указан в маршрутах. Это значение передается как аргумент в метод. Пытается обновить переданную сущность, и если удачно отсылает «200» или «202» ответ, как представление сущности.

 

- DELETE. Доступен через метод «delete ()». Требует, что бы параметр «id» был указан в маршрутах. Это значение передается как аргумент в метод. . Пытается удалить переданную сущность, и если удачно отсылает «200» или «204» ответ, как статус.

 

Так же можно отобразить метод «action» в AbstractRestfulController,  если используете AbstractActionController. Эти методы будут проименованы с добавлением суффикса «Action», продифиринцированы от методов RESTful, описанных выше. Это позволяет использовать такие действия, как предоставление форм, использующихся для подписки на различные методы RESTfulили для добавления «RPC» методов в Ваше RESTful API.

 

 

Интерфейсы

 

AbstractRestfulController реализует все эти интерфейсы:

- Zend\Stdlib\DispatchableInterface

- Zend\Mvc\InjectApplicationEventInterface

- Zend\ServiceManager\ServiceLocatorAwareInterface

- Zend\EventManager\EventManagerAwareInterface

 

EventManager настроен на прослушивание следующего контектса:

- Zend\Stdlib\DispatchableInterface

- Zend\Mvc\Controller\AbstractActionController

 

Если же Вы решите расширить класс, то прослушиваться будет класс-расширитель.


Автор статьи: DuB