Для обеспечения большей гибкости, пакет (bundle) может содержать ряд конфигурационных настроек, используя встроенный механизм Symfony2.
Простая конфигурация
Для простой конфигурации можно воспользоваться разделом parameters, по-умолчанию присутствующим в конфигурации Symfony2. Параметры – это простые пары ключ-значение; значением может быть любое валидное значение с точки зрения PHP. Каждое наименование параметра должно начинаться с наименования пакета в нижнем регистре (hello для HelloBundle, или sensio.social.blog для SensioSocialBlogBundle).
Пользователь может задавать значения в любом конфигурационном файле:
- YAML
# app/config/config.yml parameters: hello.email.from: fabien@example.com
- XML
<!-- app/config/config.xml --> <parameters> <parameter key="hello.email.from">fabien@example.com</parameter> </parameters>
- PHP
// app/config/config.php $container->setParameter('hello.email.from', 'fabien@example.com');
- INI
[parameters] hello.email.from = fabien@example.com
Получить параметры в коде можно из контейнера:
$container->getParameter('hello.email.from');
Не смотря на то, что этот механизм является достаточно простым, настоятельно рекомендуется использовать семантические конфигурации описанные ниже.
Семантическая конфигурация
Семантическая конфигурация имеет бОльшую гибкость в конфигурировании пакетов и превосходит простые параметры по следующим показателям:
- Возможность определить больше чем просто параметры (например сервисы);
- Лучшая иерархия в конфигурации (вы можете определять вложенные конфигурации);
- “Умные” слияния (merging), когда несколько файлов конфигурации переопределяют существующую конфигурацию;
- Валидация конфигурации (если вы определите XSD файл и используете XML);
- Завершение при использовании XSD и XML (прим. пер: видимо тут имеется в виду автозавершение в IDE на основе XSD структуры XML)
Создание расширения (Extension)
Для того чтобы использовать семантическую конфигурацию, создайте расширение Dependency Injection, которое наследуется от Extension:
// HelloBundle/DependencyInjection/HelloExtension.php use SymfonyComponentDependencyInjectionExtensionExtension; class HelloExtension extends Extension { public function configLoad($config, ContainerBuilder $container) { // ... } public function getXsdValidationBasePath() { return __DIR__.'/../Resources/config/'; } public function getNamespace() { return 'http://www.example.com/symfony/schema/'; } public function getAlias() { return 'hello'; } }
Класс, описанный выше определяет пространство имен hello:config, доступное в любом конфигурационном файле:
- YAML
# app/config/config.yml hello.config: ~
- XML
<!-- app/config/config.xml --> <?xml version="1.0" ?> <container xmlns="http://www.symfony-project.org/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:hello="http://www.example.com/symfony/schema/" xsi:schemaLocation="http://www.example.com/symfony/schema/ http://www.example.com/symfony/schema/hello-1.0.xsd"> <hello:config /> ... </container>
- PHP
// app/config/config.php $container->loadFromExtension('hello', 'config', array());
Разбор конфигурации
Всякий раз, когда пользователь включает пространство имен hello.config в конфигурационный файл, вызывается метод configLoad() вашего расширения и конфигурация передается в виде массива (Symfony2 автоматически конвертирует XML и YAML в массивы).
Итак, мы имеем следующую конфигурацию:
- YAML
# app/config/config.yml hello.config: foo: foo bar: bar
- XML
<!-- app/config/config.xml --> <?xml version="1.0" ?> <container xmlns="http://www.symfony-project.org/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:hello="http://www.example.com/symfony/schema/" xsi:schemaLocation="http://www.example.com/symfony/schema/ http://www.example.com/symfony/schema/hello-1.0.xsd"> <hello:config foo="foo"> <hello:bar>foo</hello:bar> </hello:config> </container>
- PHP
// app/config/config.php $container->loadFromExtension('hello', 'config', array( 'foo' => 'foo', 'bar' => 'bar', ));
Массив, который будет передаваться в ваш метод будет таким:
array( 'foo' => 'foo', 'bar' => 'bar', )
Внутри метода configLoad() переменная $container ссылается на контейнер, который знает лишь об этом пространстве имен. Вы можете манипулировать добавлением сервисов и параметров в нужном вам направлении. Когда метод вызывается первый раз, контейнер знает лишь о глобальных параметрах. При последующих вызовах он содержит конфигурацию, определенную предыдущими вызовами. Таким образом метод должен объединить новые настройки со старыми:
// only load default services and parameters once if (!$container->hasDefinition('xxxxx')) { $loader = new XmlFileLoader($container, __DIR__.'/../Resources/config'); $loader->load('hello.xml'); }
Глобальные параметры:
- kernel.name
- kernel.environment
- kernel.debug
- kernel.root_dir
- kernel.cache_dir
- kernel.logs_dir
- kernel.bundle_dirs
- kernel.bundles
- kernel.charset
Соглашения по созданию расширений
При создании расширения следуйте этим простым соглашениям:
- Расширение должно находиться во вложенном пространстве имен DependencyInjection;
- Расширение должно именоваться при помощи наименования пакета и завершаться суффиксом Extension (HelloExtension для HelloBundle) – если же вы создаете несколько расширений для одного пакета, просто завершайте их суффиксом Extension;
- Алиас должен быть уникальным и должен именоваться также при помощи наименования пакета (hello для HelloBundle или sensio.social.blog для SensioSocialBlogBundle);
- Расширение должно содержать XSD схему.
Если вы последуете этим рекомендациям, то ваше расширение автоматически будет зарегистрировано Symfony2. Если этого не произошло, переопределите метод пакета registerExtensions():
class HelloBundle extends Bundle { public function registerExtensions(ContainerBuilder $container) { // register the extension(s) found in DependencyInjection/ directory parent::registerExtensions($container); // register extensions that do not follow the conventions manually $container->registerExtension(new ExtensionHello()); } }
Конфигурация по-умолчанию
Как определено ранее, пользователь пакета должен включить пространство имен hello.config в конфигурационный файл, для того чтобы вызывался код вашего расширения. Но вы также можете автоматически регистрировать конфигурацию по-умолчанию, переопределяя метод пакета registerExtensions():
class HelloBundle extends Bundle { public function registerExtensions(ContainerBuilder $container) { // will register the HelloBundle extension(s) found in DependencyInjection/ directory parent::registerExtensions($container); // load some defaults $container->loadFromExtension('hello', 'config', array(/* your default config for the hello.config namespace */)); } }
Внимание: Symfony2 старается быть максимально открытым и понятным. Поэтому определение конфигурации по-умолчанию автоматически это наверняка не очень хорошая идея.
Оригинал тут: http://docs.symfony-reloaded.org/guides/bundles/configuration.html
Перевод как всегда – мой авторский ))
Спасибо за переводы. А нет ли желания какую-нить статейку про свой опыт использования сф2 сделать?
До релиза symfony2 наверное нет. Не хочу ничего серьезно на него портировать пока нет стабильной версии. Ну или с нуля делать. Да и понимания пока хорошего нет, в частности поэтому и перевожу – сам же потом читать буду )
Статью можно сливать, уже совершенно не актуально =)
Ну почему же, аналога конечно уже нет, но и prameters и semantic extensions также есть. Про semantic осталась заметка в cookbook http://symfony.com/doc/2.0/cookbook/bundles/extension.html
А мы вот начали делать крупный проект на symfony2. Раньше хотели на sf1.x, но передумали.
Трахаться приходится изрядно, но очень нравится новое!
Twig вообще офигительная вещь!
Ну… я можно сказать его немного побаиваюсь… (( Вот и медлю…