Создаем свой Фреймворк на компонентах Symfony2

Я совершенно не фанат Symfony2. У меня нет ни одного проекта на этом фреймворке, и вряд ли когда-нибудь хоть один появится. Это к тому, что я решил перевести цикл статей “Создаем свой Фреймворк на компонентах symfony2” совсем не из-за Symfony2. Этот цикл должен прочесть каждый. Этот цикл про программирование, про ООП, про архитектуру. Этот цикл — best practices разработки проектов на PHP. Изначально, конечно, Фабьен Потенсьер, автор оригинального текста и создатель Symfony2, задумывал эти статьи как рекламу своего фреймворка. Но что-то пошло не так…

Содержание цикла:

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 12

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

Сам фронт-контроллер стал куда более лаконичным:

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 11

Если бы вы использовали наш фреймворк прямо сейчас, вы бы наверняка задумались о поддержке кастомных сообщений об ошибках. Мы уже имеем обработку для ошибок 404 и 500, но способ обработки захардкоден во фреймворке. Сделать их кастомизацию — легче легкого, достаточно определить новое событие, и слушателя, который будет вызывать по этому событию определенный контроллер. Вроде все просто, но, что если, в этом контроллере выбросить исключение? Вы получите бесконечный цикл! Не самый лучший вариант правда?

Посмотрим на класс HttpKernel, который является универсальной, расширенной и гибкой имплементацией интерфейса HttpKernelInterface. Этот класс очень похож на класс фреймворка, который мы пишем. Он управляет событиями в некоторых важных участках кода в процессе обработки запроса. Он использует Controller resolver, для сопоставления контроллера запросу. И в качестве бонуса, он предоставляет отличную обратную связь, при возникновении проблем.

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 10

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

HttpKernelInterface, наверное, самая важная часть кода в компоненте HttpKernel. Фреймворки и приложения реализующие этот интерфейс полностью совместимы. Более того, эта возможность может принести вам много отличного функционала.

Усовершенствуем фреймворк, для реализации данного интерфейса:

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 9

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

О каком внедрении функционала я говорю? Например аутентификация, или кэширование инстансов. Причем внедрение функционала должно быть plug-and-play. По такому принципу работают например Drupal и WordPress. Часто эта возможность даже предусмотрена на уровне языка программирования, например WSGY в Python или Rack в Ruby.

Так как в PHP ничего подобного на уровне языка не предусмотрено, мы будем использовать хорошо известный шаблон Наблюдатель (Observer). В Symfony2 компонент EventDispatcher реализует упрощенную версию этого шаблона.

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 8

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

Сегодняшняя задача — написать юнит-тесты для нашего фреймворка, с помощью PHPUnit.

Создадим файл конфигурации для PHPUnit phpunit.xml.dist:

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 7

Сейчас в нашем фреймворке есть один минус. Нам нужно копипастить код во front.php каждый раз, как мы создаем сайт. 40 строк кода — это не так уж и много, но было бы неплохо обернуть этот код в класс, что даст нам возможность многократного использования, и лучшую тестируемость кода.

Если присмотреться к front.php — можно увидеть, что мы принимаем данные запроса и выводим ответ. Наш класс будет придерживаться простого принципа: вся логика ограничена созданием ответа для запроса.

Так как, компоненты Symfony2 все равно требуют PHP 5.3, давайте для нашего класса определим пространство имен Simplex, и перенесем в него логику обработки запроса:

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 6

Вы наверное думаете, что наш фреймворк уже достаточно хорош, и вы правы! Но, тем не менее, давайте посмотрим, как мы можем сделать его еще лучше.

Сейчас все наши примеры используют процедурный код, но помните, что контроллеры могут быть любыми валидными объектами типа PHP callbacks. Давайте представим наш контроллер в виде класса.

И, соответственно, обновим определение маршрута.

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 5

Внимательный читатель заметил, что в нашем фреймворке захардкоден способ определения шаблона. Для простейших страничек, типа тех, которые мы создавали ранее — это не проблема. Но если вы захотите добавить немного логики — вам придется добавлять логику в сам шаблон, что, в общем, не самая хорошая идея.

Давайте разделим код шаблонов и логику, добавив новый слой: Контроллер. Задача контроллера — генерировать ответ, основываясь на информации, переданной клиентским запросом.

Измените часть фреймворка, отвечающую за отображение шаблонов следующим образом:

(далее…)

Создаем свой Фреймворк на компонентах symfony2. Часть 4

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

Раз мы распаковали параметры запроса, то можем упростить hello.php следующим образом:

(далее…)