in Профессиональное

Symfony 2.0 – быстрый тур – архитектура/the architecture (часть 5)

Первые 4 части этого руководства позволили составить обще представление о Symfony 2.0. Но они не останавливаются на структуре директорий проекта. Поскольку это одна из отличительных особенностей Symfony, давайте-ка остановимся на этом подробнее.

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

Структура директорий / The Directory Structure

Структура директорий песочницы отражает типовую и рекомендованную структуру приложения Symfony:

  • hello/: Эта директория, названная по имени вашего приложения, содержит конфигурационные файлы;
  • src/: Весь PHP код находится в этой директории;
  • web/: Это директория web root.

Директория web / The Web Directory

Корень веб – это домашняя директория для всех публичных и статических файлов типа изображений, стилей и javascript-файлов. Она также содержит боевой фронт-контроллер:

# web/index.php
<?php

require_once __DIR__.'/../hello/HelloKernel.php';

$kernel = new HelloKernel('prod', false);
$kernel->run();

Как и любой другой фронт-контроллер, index.php использует Kernel Class, HelloKernel, для инициализации и запуска приложения.

Директория приложения / The Application Directory

Класс HelloKernel это главная точка входа  в настройки приложения и он хранится в директории hello/.

Этот класс должен реализовывать 5 методов:

  • registerRootDir(): Возвращает корневую директорию;
  • registerBundles(): Возвращает массив всех пакетов (бандлов) нобходимых для запуска приложения (обратите внимание на ApplicationHelloBundleBundle);
  • registerBundleDirs(): Возвращает массив ассоциаций пространств имен и их домашних директорий;
  • registerContainerConfiguration(): Возвращает главный конфигурационный объект (об этом подробнее ниже);
  • registerRoutes(): Возвращает конфигурацию маршрутизатора.

Обратите внимание на дефолтную реализацию этих методов для того чтобы лучше понять гибкость фреймворка. В начале этого руководства вы открывали файл hello/config/routing.yml. Этот путь был сконфигурирован в методе registerRoutes():

public function registerRoutes()
{
  $loader = new RoutingLoader($this->getBundleDirs());

  return $loader->load(__DIR__.'/config/routing.yml');
}

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

Для того чтобы это все работало, ядро подключает два файла из директории src/:

# hello/HelloKernel.php
require_once __DIR__.'/../src/autoload.php';
require_once __DIR__.'/../src/vendor/symfony/src/Symfony/Foundation/bootstrap.php';

Директория исходных кодов / The Source Directory

Файл src/autoload.php отвечает за автозагрузку всех файлов из директории src/:

# src/autoload.php
require_once __DIR__.'/vendor/symfony/src/Symfony/Foundation/UniversalClassLoader.php';

use SymfonyFoundationUniversalClassLoader;

$loader = new UniversalClassLoader();
$loader->registerNamespaces(array(
  'Symfony'     => __DIR__.'/vendor/symfony/src',
  'Application' => __DIR__,
  'Bundle'      => __DIR__,
  'Doctrine'    => __DIR__.'/vendor/doctrine/lib',
));
$loader->registerPrefixes(array(
  'Swift_' => __DIR__.'/vendor/swiftmailer/lib/classes',
  'Zend_'  => __DIR__.'/vendor/zend/library',
));
$loader->register();

// for Zend Framework & SwiftMailer
set_include_path(__DIR__.'/vendor/zend/library'.PATH_SEPARATOR.__DIR__.'/vendor/swiftmailer/lib'.PATH_SEPARATOR.get_include_path());

Класс UniversalClassLoader используется для автозагрузки файлов, которые удовлетворяют либо техническому стандарту для пространств имен в PHP 5.3 или же соглашению о наименовании классов PEAR. Как вы можете видеть, все зависимости хранятся в директории vendor/, но, это всего-лишь соглашение. Вы можете хранить их где вам удобно, глобально на сервере или локально в вашем проекте.

Еще немного о пакетах / More about Bundles

Как мы могли видеть в предыдущей части, приложение состоит из пакетов, определенных в методе registerBundles():

# hello/HelloKernel.php
public function registerBundles()
{
  return array(
    new SymfonyFoundationBundleKernelBundle(),
    new SymfonyFrameworkWebBundleBundle(),
    new SymfonyFrameworkDoctrineBundleBundle(),
    new SymfonyFrameworkSwiftmailerBundleBundle(),
    new SymfonyFrameworkZendBundleBundle(),
    new ApplicationHelloBundleBundle(),
  );
}

Но как же Symfony понимает где искать пакеты? Symfony очень гибок в этом отношении. Метод registerBundleDirs() должен возвращать ассоциативный массив, который ставит в соответствие пространству имен некоторую валидную директорию (локальную или глобальную):

public function registerBundleDirs()
{
  return array(
    'Application'        => __DIR__.'/../src/Application',
    'Bundle'             => __DIR__.'/../src/Bundle',
    'Symfony\Framework' => __DIR__.'/../src/vendor/symfony/src/Symfony/Framework',
  );
}

Итак, когда вы ссылаетесь на HelloBundle в имени контроллера или в имени шаблона, Symfony будет искать его в указанных директориях.

Ну как, вы поняли почему Symfony такой гибкий? Используйте ваши пакеты в различных приложениях, храните их локально или глобально на ваш выбор.

Вендоры / Vendors

Часто ваше приложение будет зависеть от сторонних библиотек. Они должны храниться в директории src/vendor/. Она уже содержит библиотеки Symfony – SwiftMailer, Doctrine ORM, и избранное из классов Zend Framework.

Кэш и логи / Cache and Logs

Symfony это один из самых быстрых фреймворков. Но как он может быть таким быстрым, если он постоянно должен парсить и интерпретировать десятки YAML и XML файлов? Частично это обязанность системы кеширования. Конфигурация приложения парсится только для первого запроса и после этого компилируется в обычный PHP код, который хранится в директории приложения cache/. В девелоперском окружении Symfony сбрасывает кэш когда вы изменяете файл, но в продуктовом окружении это уже ваша обязанность чистить кэш, когда вы обновляете ваш код или конфигурацию.

Во время разработки web-приложения что-то может пойти не так в любой момент. Файлы логов в директории приложения logs/ могут рассказать вам подробности о запросах и помочь разобраться в проблеме, не затратив много времени.

Интерфейс командной строки / The Command Line Interface

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

Запустите консоль без агрументов, для того чтобы получить представление о ее возможностях:

$ php hello/console

Опция --help поможет вам уточнить способ использования любой команды:

$ php hello/console router:debug --help

Последний рывок / Final Thoughts

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

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

Источник: http://symfony-reloaded.org/quick-tour-part-5

P.S. На текущий момент, увы, на официальном сайте проекта следующей главы, на которую ссылается автор, пока нет. Так что пока повременим становиться мастерами симфонии (ваш hudson).

Leave a Reply for Krion Cancel Reply

Write a Comment

Comment

ERROR: si-captcha.php plugin: GD image support not detected in PHP!

Contact your web host and ask them to enable GD image support for PHP.

ERROR: si-captcha.php plugin: imagepng function not detected in PHP!

Contact your web host and ask them to enable imagepng for PHP.

15 Comments

  1. Hudson, можно совет? Можно ли сейчас запускать проект на 2.0 или он еще совсем сырой? Просто я в английском не силен и не совсем понимаю являеться ли текущий дистрибив симфони рабочим. Просто как мне показалась 2.0 сильно отличаеться от 1.4 и если я свой проект сделаю на 1.4 – сложно будет обновиться до 2.0.

    • Обновиться на 2.0 на мой взгляд будет совершенно невозможно. Только портировать код, что по сути будет означать переписывание приложения заново.

      Сами разработчики
      а) совершенно не рекомендуют сейчас использовать 2.0 для продуктовых проектов.
      б) но просят тестировать на маленьких не критичных проектиках (например внутренние тулы).

      Так что делайте на 1.4 мой совет. На 2.0 для продуктовых решений смотреть можно будет не раньше бета релиза. А еще лучше релиз-кандидата.

  2. Спасибо hudson за твои труды! Так держать!!!

    Надо будет все это собрать воедино.

  3. подскажите, а можно как-либо с помощью консоли генерировать приложения? (на подобии “rails имя_приложения”?) А то копировать скелетоны как-то совсем не кашерно. А так спасибо за статьи, 2-я симфони очень интересна, с первой правда дела не имел

    • Пожалуйста! На следующей неделе надеюсь продолжить статью про symfony2 + facebook, а также перевод статей с symfony.com. Кстати, а какая бы статья для вас представляла наибольший интерес?

  4. Самый активный блог по симфони. Спасибо за работу, с нетерпением жду новых статей!