На данный момент 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 файлы. Можно отключать либо заменять части самого фреймворка путем отключения или замены «бандлов».
Теперь можно кратко ознакомиться с содержимым самого фреймворка, что я сделаю в следующей части.