В этой статье попробуем разобраться с компонентом под название Config, который помогает загружать и обрабатывать различные данные независимо от источника. Ниже представлен перевод статьи Symfony2 components overview: Config. Оригинал был опубликован в 2014 году и в нем указывается вторая версия Symfony, но информация актуальна и для последней, на данный момент, четвертой версии. Давайте представим, что мы хотим создать генератор блогов, который будет принимать несколько параметров таких как заголовок(title), описание(description), количество постов на главной странице(posts_main_page), иконки соцсетей(social) и наличие или отсутствие RSS ленты(rss). Для этих целей, мы опишем конфигурационный файл в формате YAML: Теперь попробуем распарсить наш файл, проверим наличие обязательных полей, установим при необходимости значения по умолчанию. Все полученные данные проверим на соответствие установленным правилам, например rss может содержать только булевое значение, а в posts_main_page должно находиться целочисленное значение в интервале от 1 до 10. Эти процедуры нам придется повторять каждый раз при обращении к файлу, если же конечно не используется система кеширования. Кроме того подобный механизм усложняет использование файлов других форматов как INI, XML или JSON. Для упрощения вышеперечисленных действий, воспользуемся компонентом Config. Компонент прост, хорошо тестируется и достаточно гибок для использования в разных проектах. Разделим проект на две основные части: Давайте вернемся к нашему примеру. И так, мы хотим создать гибкую систему генерации блогов. Для начала определим иерархическую структуру(дерево), а поможет нам в этом экземпляр класса TreeBuilder, который предоставляет DSL-синтаксис подобный интерфейс. Не переживайте, если вы видите подобную структуру PHP кода в первый раз, DSL-синтаксис в нем, всегда выглядит немного странно. В примере выше, мы определили корневой узел blog и от него выстроили структуру дерева конфигурации, ветвями которого являются необходимые нам параметры и правила к их значениям. К примеру title обозначен как обязательный параметр скалярного типа, description как опциональный параметр, который по умолчанию пуст, в rss ожидаем булевое значение, которое по умолчанию равно false, а posts_main_page должен содержать целочисленное значение в диапазоне от 1 до 10, при этом 5 по умолчанию. Отлично, структуру мы определили, теперь давайте займемся загрузкой и обработкой. По условию, источник может быть любым, для начала нам нужно преобразовать его в обычный массив, чтобы в дальнейшем проверить и обработать все значения используя нашу конфигурационную структуру. Для каждого формата источника нам потребуется отдельный класс, так если мы собираемся использовать форматы файлов YAML и XML нам нужно создать два класса. В примере ниже представлен для простоты только класс формата YAML: Как видите все очень просто. Метод YamlConfigLoader::supports используется классом LoaderResolver для проверки источника конфигурации. Метод YamlConfigLoader::load преобразовывает YAML файл в массив данных используя другой Symfony компонент YAML. В завершении, мы объединяем конфигурационную структуру и загрузчик при обработке источника для получения необходимых значений: Давайте разберем данный код. Сначала мы определяем массив директорий где могут находиться конфигурационные файлы, и помещаем его в качестве параметра в объект FileLocator который ищет файл config.yml в указанной директории. Затем, создаем объект YamlConfigLoader, который возвращает массив со значениями, и уже он обрабатывается нашей конфигурационной структурой. В результате получим следующий массив: Если попробуем изменить config.yml удалив rss и post_main_page поля, то получим значения по умолчанию: Обработка больших конфигурационных файлов может стать ресурсоемкой задачей. Описываемый компонент обладает простым механизмом кэширования основанной на проверке даты изменения файла конфигурации. Для включения кэша достаточно нескольких строк кода: Экземпляр класса ConfigCache проверяет существование кэша файла и при наличии сравнивает дату изменения конфигурационного файла. Когда мы создаем кэш файла мы также сохраняем список используемых объектов для дальнейшего сопоставления. Для добавления другого формата конфигурации, достаточно определить класс который будет отвечать за конкретный формат. В примере ниже, мы добавили поддержку XML конфигурации и соответствующий обработчик. Класс LoaderResolver поможет нам объединить разные форматы в общий пул, а класс DelegatingLoader загрузит по запросу необходимый файл. Помимо прочего, компонент обладает функционалом для генерации справочной информации к вашей документации. Будет выведено: Возможно вы посчитаете, что все это слишком сложно и запутанно, и можно обойтись парочкой функций. Возможно, но такова «цена» за хорошую ООП структуру. С другой стороны, данный компонент предлагает ряд преимуществ: