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