Если вы используете наш фреймворк, вы наверно хотели бы добавить поддержку настройки отображения ошибок. Сейчас мы поддерживаем 404 и 500 ошибки, но они хардкорно забиты в коде. Сделать так, чтобы можно было настраивать их довольно легко: добавить новое событие и слушателя в диспетчер. Т.е. слушатель должен вызывать обычный контроллер. Но что если контроллер ошибок выбросит исключение? Будет зацикливание. Должен быть более простой способ, не так ли?

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

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

Вот новый код фреймворка:

И новый фронт-контроллер:

RouterListener реализует похожую логику, которая есть в нашем фреймворке: он согласует входящий запрос и заполняет его атрибутами из маршрута.

Наш код сейчас лаконичнее и, что самое удивительно, надежнее и мощнее, чем когда либо. Напрмер, используйте встроенный ExceptionListener чтобы сделать управление ошибками настраиваемым:

ExceptionListener возвращает объект FlattenException вместо Exception чтобы облегчить манимупилорование и отображение исключений.  Он может использовать любой валидный контроллер, таким образом вы можете создать класс ErrorController вместо того, чтобы использовать Замыкание:

Контроллер ошибок:

Вуйаля! Чистый и настраиваемый обработчик ошибок без напряга. И конечно же, если ваш контроллер выкинет исключение, HttpKernel обработает ее.

Во второй части мы говорили о методе Response::prepare(), который гарантирует, Response совместим со HTTP спецификацией. Это хорошая идея всегда вызывать его перед отправкой ответа клиенту; это то, что ResponseListener делает:

Это было сшиком просто! Давайте попробуем что-нибудь еще: хотите поддержку потоковых ответов из коробки? Легко, воспользуйтесь StreamedResponseListener:

И в ваш контроллер вернеться объект StreamedResponse вместо Response.

Прочитайте главу из документации по Symfony2 Internals, чтобы лучше изучить события и как они могут помочь вам изменить обработку запроса.

Теперь, давайте создадим слушателя, который позволит контроллеру вернуть строку, вместо объекта Response:

Чтобы реализовать эту фичу, мы собираемся слушать событие kernel.view, которое срабатывает только после вызова контроллера. Наша цель: сконвертировать ответ контроллера в правильный объект Response, но только, если это необходимо:

Код довольно прост, т.к. событие kernel.view срабатывает только когда контроллер возвращает строку (наш слушатель не может мешать другим).

Не забудьте зарегистрировать его во фронт-контроллере:

Если вы забудете зарегистрировать подписчика, то HttpKernel выкинет исключение: The controller must return a response (Nope, this is not a leap year given)…

Сейчас, наш фреймворк компактный и состоит из комбинации существующих библиотек. Расширяем только когда регистрируем слушателей/подписчиков.

Надедсь, теперь вы понимаете почему простой HttpKernelInterface настолько мощный. Реализация HttpKernel дают вам доступ к кучу крутых фич, прямо из коробки. И т.к. HttpKernel используется в Symfony2 и Silex, у вас теперь комбинация из 2 миров: свой фреймворк, заточенный под ваши нужды, но основанный на незыблемой и хорошо поддерживаемой низкоуровневой структуре, проверенной на множестве сайтах; код, который провер и хорошо масштабируем.