Symfony 2 претерпел серьезные изменения в сравнении с 1.x веткой. Фреймворк стал более гибким и быстрым. Теперь, по заявлениям разработчиков — это один из самых быстрых фреймворков написанных на PHP, на цифры можно посмотреть тут. Однако не стоит воспринимать эти заявления близко к сердцу, что действительно важно — он стал быстрее и гибче.
На данный момент Symfony 2 еще находится в разработке и не готов к использованию в production. Но попробовать в целях изучения, его уже можно. Ознакомление я хочу начать с обзора приложения базирующегося на фреймворке. Исходники Symfony 2 на github. Там же на github есть готовое приложение sandbox построенное на Symfony 2.0, но в нем версия Symfony несколько отличается от последней. Поэтому после получения исходников sandbox, первым делом я заменил версию Symfony в
Итак, первым, что бросается в глаза — структура директорий приложения совершенно другая. А именно есть три директории: hello, src, web.
Корневая директория веб сервера содержит все доступные из веб файлы, такие как изображения, таблицы стилей, javascript. Также здесь находятся фронт контроллеры
Фронт контроллер подключает класс ядра приложения, создает экземпляр класса, определяя окружение и запускает приложение вызывая метод
В директории приложения
В этой же директории находится файл
Здесь же находятся директории:
В директории исходных кодов
В HelloBundle содержатся:
Важный момент — фреймворк не определяет структуру директорий и не накладывает никаких ограничений. Если заглянуть в класс ядра нашего приложения, то увидим, что все пути прописаны именно там. И мы можем менять их по своему усмотрению. Данная структура директорий предложена именно приложением sandbox и вероятно будет в дальнейшем предлагаться как дефолтная.
Рассмотрев структуру директорий приложения можно попробовать выяснить где же скрывается обещанная гибкость и что конкретно можно поменять. Ну, если честно, сама структура директорий — это первое, что мы можем менять по своему усмотрению. В Symfony 1.x была директория
Следующее интересное место — «бандлы» (bundles). «Бандл» — это «first-class citizens» в Symfony, это структурированный набор файлов реализующих определенную функциональность и который легко может быть использован другими разработчиками в других приложениях. Это не совсем тоже самое, что и плагины в Symfony 1.x, как я сказал выше. Ближайшая аналогия, которую я для себя нашел — это «application» в Django. В Symfony 2 все состоит из «бандлов», сам фреймворк — это набор «бандлов», приложение, которое вы разрабатываете также является «бандлом», либо набором «бандлов». Это позволяет гибко настраивать приложения и подключать функциональность упакованную в «бандлы», также это дает возможность распространять код упаковывая его в «бандл».
Например в приложении sandbox, которое я взял с github, если заглянуть в класс ядра, то можно увидеть какие «бандлы» используются и это будут:
Исходя из того, что все что делает приложение — это печатает Hello и имя переданное в параметрах, можно смело отключить DoctrineBundle, SwiftmailerBundle.
Каждый «бандл» можно кастомизировать используя конфигурационные файлы. Конфиги приложения находятся в директории
Интересно, что файлы
Каждое вхождение, вроде
Для каждого окружения можно перекрывать настройки «бандлов», например как это сделано в
Итак, подводя итог обзора приложения, можно выделить следующие интересные моменты. Фреймворк базируется на идее микро-ядра с подключаемыми «бандлами». Связывается это все используя Dependency Injection Container. В результате можно добавлять/удалять функциональность в приложении за счет подключения/отключения «бандлов», которые также можно кастомизировать используя конфигурационные Yaml или XML файлы. Можно отключать либо заменять части самого фреймворка путем отключения или замены «бандлов».
Теперь можно кратко ознакомиться с содержимым самого фреймворка, что я сделаю в следующей части.
На данный момент Symfony 2 еще находится в разработке и не готов к использованию в production. Но попробовать в целях изучения, его уже можно. Ознакомление я хочу начать с обзора приложения базирующегося на фреймворке. Исходники Symfony 2 на github. Там же на github есть готовое приложение sandbox построенное на Symfony 2.0, но в нем версия Symfony несколько отличается от последней. Поэтому после получения исходников sandbox, первым делом я заменил версию Symfony в
src/vendor/symfony
на последнюю.git clone git://github.com/symfony/symfony-sandbox.git sandbox cd sandbox/src/vendor rm -rf symfony git clone git://github.com/symfony/symfony symfony
Итак, первым, что бросается в глаза — структура директорий приложения совершенно другая. А именно есть три директории: hello, src, web.
hello/
: директория названная в честь приложения и содержащая конфигурационные файлы.src/
: весь PHP код хранится здесь.web/
: корневая директория веб сервера.
Корневая директория веб сервера содержит все доступные из веб файлы, такие как изображения, таблицы стилей, javascript. Также здесь находятся фронт контроллеры
index.php
— для production окружения и index_dev.php
— для development окружения. В общем, все как и раньше, за одним исключением, здесь появился полезный скрипт check.php
позволяющий проверить окружение на соответствие системным требованиям Symfony 2.0. Фронт контроллер подключает класс ядра приложения, создает экземпляр класса, определяя окружение и запускает приложение вызывая метод
run
.В директории приложения
hello/
содержится класс ядра приложения, который расширяет абстрактный класс Symfony\Foundation\Kernel
и производит основные определения. В частности здесь определяется корневая директория приложения, регистрируются «бандлы» (то из чего теперь состоит Symfony и приложения построенные на нем), регистрируются пути по которым следует искать «бандлы», создается Dependency Injection Container и регистрируются правила маршрутизации (routing). Методы создающие IOC контейнер и определяющий правила маршрутизации в реализации по умолчанию загружают конфигурационные файлы из директории приложения hello/
. Здесь же в классе ядра подключаются два важных файла src/autoload.php
и src/vendor/symfony/src/Symfony/Foundation/bootstrap.php
необходимые для правильной работы ядра, в частности в autoload.php
создается экземпляр класса Symfony\Foundation\UnversalClassLoader
и настраиваются пути для авто-загрузки файлов с классами. Пути задаются двумя методами registerNamespaces
— позволяющим задать пути для поиска классов по их пространствам имен (namespace) и registerPrefixes
— позволяющим задать пути поиска файлов по префиксам классов, например Swift_
, Zend_
т.е. для классов написанных в стиле PHP версии ниже 5.3В этой же директории находится файл
hello/console
— аналог файла symfony
в Symfony 1.x, т.е. инструмент позволяющий выполнять различные команды из консоли.Здесь же находятся директории:
hello/cache
: для кешаhello/logs
: для логовhello/config
: для конфигурационных файлов
В директории исходных кодов
src/
находятся уже упомянутый выше файл src/autoload.php
и директории:src/Application
: содержит «бандлы» нашего веб приложения, в данном случае HelloBundlesrc/Bundle
: содержит сторонние, либо расшариваемые между несколькими приложениями «бандлы», в нашем случае здесь ничего нетsrc/vendor
: содержит исходный код сторонних библиотек, в нашем случае содержитdoctrine
,swiftmailer
,symfony
,zend
В HelloBundle содержатся:
- класс «бандла» Bundle расширяющий класс Symfony\Foundation\Bundle\Bundle, который в свою очередь реализует интерфейс Symfony\Foundation\Bundle\BundleInterface
HelloBundle/Controller/HelloController.php
: контроллер приложенияHelloBundle/Resources
: ресурсы «бандла» в том числе шаблоны
Важный момент — фреймворк не определяет структуру директорий и не накладывает никаких ограничений. Если заглянуть в класс ядра нашего приложения, то увидим, что все пути прописаны именно там. И мы можем менять их по своему усмотрению. Данная структура директорий предложена именно приложением sandbox и вероятно будет в дальнейшем предлагаться как дефолтная.
Рассмотрев структуру директорий приложения можно попробовать выяснить где же скрывается обещанная гибкость и что конкретно можно поменять. Ну, если честно, сама структура директорий — это первое, что мы можем менять по своему усмотрению. В Symfony 1.x была директория
apps/
содержащая различные приложения использующие общий код. В нашем случае этой директории нет, но разные приложения можно создавать и делать это можно удобным для нас способом. Например можно создать директории приложения на одном уровне с src/
и web/
, т.е. как сделано в нашем случае с приложением hello
. Мы можем добавить еще одно приложение, например bye
. Либо мы можем просто добавить класс нового приложения ByeKernel
в директорию hello/
прописав в нем корневую директорию приложения. Кстати, никто не запрещает создать директорию apps/
в которой размещать приложения. В общем, в плане структуры директорий, все очень гибко.Следующее интересное место — «бандлы» (bundles). «Бандл» — это «first-class citizens» в Symfony, это структурированный набор файлов реализующих определенную функциональность и который легко может быть использован другими разработчиками в других приложениях. Это не совсем тоже самое, что и плагины в Symfony 1.x, как я сказал выше. Ближайшая аналогия, которую я для себя нашел — это «application» в Django. В Symfony 2 все состоит из «бандлов», сам фреймворк — это набор «бандлов», приложение, которое вы разрабатываете также является «бандлом», либо набором «бандлов». Это позволяет гибко настраивать приложения и подключать функциональность упакованную в «бандлы», также это дает возможность распространять код упаковывая его в «бандл».
Например в приложении sandbox, которое я взял с github, если заглянуть в класс ядра, то можно увидеть какие «бандлы» используются и это будут:
Symfony\Foundation\Bundle\KernelBundle
Symfony\Framework\WebBundle\Bundle
Symfony\Framework\ZendBundle\Bundle
Symfony\Framework\SwiftmailerBundle\Bundle
Symfony\Framework\DoctrineBundle\Bundle
Application\HelloBundle\Bundle
Исходя из того, что все что делает приложение — это печатает Hello и имя переданное в параметрах, можно смело отключить DoctrineBundle, SwiftmailerBundle.
Каждый «бандл» можно кастомизировать используя конфигурационные файлы. Конфиги приложения находятся в директории
hello/config/
. В частности там есть:hello/config/config.yml
: общие настройкиhello/config/config_dev.yml
: настройки для dev окруженияhello/config/config_prod.yml
: настройки для prod окруженияhello/config/routing.yml
: правила маршрутизации
Интересно, что файлы
config_dev.yml
и config_prod.yml
подключают файл config.yml
иcпользуя инструкцию imports
это очень удобно. Если открыть файл config.yml
, то в нем есть настройки для подключаемых «бандлов». #hello/config/config.yml kernel.config: ~ web.web: ~ web.templating: ~
Каждое вхождение, вроде
kernel.config
определяет настройки для «бандла». Некоторые «бандлы» могут иметь несколько вхождений, как например WebBundle
, который имеет два вхождения web.web
и web.templating
Для каждого окружения можно перекрывать настройки «бандлов», например как это сделано в
config_dev.yml
:# hello/config/config_dev.yml imports: - { resource: config.yml } web.debug: exception: %kernel.debug% toolbar: %kernel.debug% zend.logger: priority: info path: %kernel.root_dir%/logs/%kernel.environment%.log
Итак, подводя итог обзора приложения, можно выделить следующие интересные моменты. Фреймворк базируется на идее микро-ядра с подключаемыми «бандлами». Связывается это все используя Dependency Injection Container. В результате можно добавлять/удалять функциональность в приложении за счет подключения/отключения «бандлов», которые также можно кастомизировать используя конфигурационные Yaml или XML файлы. Можно отключать либо заменять части самого фреймворка путем отключения или замены «бандлов».
Теперь можно кратко ознакомиться с содержимым самого фреймворка, что я сделаю в следующей части.