Configuration

При создании бандла,  который будет использоваться как библиотека (и не только), полезно будет его конфигурировать.

Конечно, можно все вынести в параметры, обойтись таким образом без конфигурации, но это будет некошерно. =)

Правильная практика описывать конфигурацию в config.yml, а часть необходимых параметров выносить в parameters.yml:

# app/config/parameters.yml
parameters:
    ...
    redis_host: localhost
    redis_port: localhost
    ...
# app/config/config.yml
you:
    ...
   redis_connection:
       host: %redis_host%
       port: %redis_port%

Мы рассмотрим, как прочитать подобный конфиг.

Кстати, если описать конфигурацию бандла и не прочитать ее, это вызовет ошибку.

Для чтения, в нашем бандле нужно описать два класса в директории DependencyInjection: Configuration и OurBundleExtension.

В Configuration происходит валидация, в YourBundleExtension уже будет доступной загруженная конфигурация и можно будет осуществлять дополнительную обработку, этому вопросу будет посвящена отдельная заметка.

Подробнее о валидации:

<?php
# src/YourVendor/YourBundle/DependensyInjection/Config.php

class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); //метод root получает ключ, по названию бандла (без самого слова bundle) $rootNode = $treeBuilder->root('your'); $rootNode ->children() ->arrayNode('redis') ->isRequired() ->children() ->scalarNode('host')->defaultValue('127.0.0.1')->end() ->integerNode('port')->defaultValue(6379)->end() ->end() ->end() ->end() ; } }

С помощью TreeBuilder мы читаем и валидируем конфигурацию. Как правило, с тривиальными конфигурациями проблем не возникает. Если задана структура, все ключи и т.д. - все просто.

Если нужно задавать неограниченное количество строк, немного по другому.

Представим себе такой конфиг (для примера):

# app/config/config.yml
you:
    ...
    redis_connection1:
        host: %redis_host%
        port: %redis_port%
    redis_connection2:
        host: %redis_host1%
        port: %redis_port2%
    ....
    redis_connectionN:
    ...

(Этот пример достаточно сферический, хотя тоже не без смысла.) В таком случае просто укажем prototype('array')

<?php
# src/YourVendor/YourBundle/DependensyInjection/Config.php

class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); //метод root получает ключ, по названию бандла (без самого слова bundle) $rootNode = $treeBuilder->root('your'); $rootNode ->children() ->arrayNode('redis') ->isRequired() ->prototype('array') ->children() ->scalarNode('host')->defaultValue('127.0.0.1')->end() ->integerNode('port')->defaultValue(6379)->end() ->end() -end() ->end() ; } }

Как уже говорили, это всего лишь валидация. Полезная возможность - использования условий:

....
$rootNode = $treeBuilder->root('your');
$rootNode
    ->children()
        ->arrayNode('redis')
            ->beforeNormalization()
                ->ifTrue(function ($v) { return is_array($v) })
                ->then(function ($v) {
                   // Addition handle here
                   return $v;
                })
            ->end()
        ->end()
...

Таким образом можно осуществить дополнительную обработку данных, даже поменять структуру конфига, сделать их валидными. Возможные node types:

  • scalar
  • boolean
  • integer
  • float
  • enum
  • array
  • variable

Последний тип стоит использовать когда все уже совсем плохо и данные нельзя провалидировать обычными способами - node типу variable не валидируется. И не забывайте читать документацию =) http://symfony.com/doc/current/components/config/definition.html