Управление конфигурацией — это организация параметров, характерных для экземпляра веб-приложения. В то время как многие языки программирования имеют четкое различие между исходным кодом и бинарными пакетами, в PHP линия разграничения не так проста. Редактировать php-скрипт очень просто, так как не нужно выполнять этап компиляции (
кэширование кода операции прозрачно для среднего разработчика и происходит на веб-сервере, а не перед распространением.) Кроме того, файлы, не относящиеся к PHP, предназначенные для настройки, должны быть тщательно размещены вне корня документа, чтобы предотвратить их возможную загрузку от вредоносных объектов.
Эти две причины привели к тому, что первые поколения PHP-приложений жестко настраивают конфигурацию в тех же PHP-скриптах, которые выполняют бизнес-логику. Такие параметры, как абсолютные пути и пароли базы данных, являются примерами встроенных строк, которые часто встречаются в устаревших приложениях PHP.
Однако существуют веские причины избегать жесткого кодирования. Внешние файлы конфигурации удаляют дублирование параметров, разбросанных по разным сценариям PHP, и концентрируют в одном стандартном месте информацию, необходимую для запуска приложения или перемещения его на другой хостинг.
Более того, конфигурация и бизнес-логика имеют два разных жизненных цикла. Конфигурация изменяется при настройке какого-либо параметра или при развертывании нового компонента; как правило, он не очень часто изменяется на рабочем сервере.
Само приложение PHP представляет собой пакет без сохранения состояния, который не отличается от других экземпляров на других серверах. Чем больше конфигурация и состояние изолированы от сценариев бизнес-логики, тем больше последние могут быть обновлены и заменены без уведомления внешних пользователей. Обновление библиотек и CMS — типичная ситуация, когда вы хотите обновить как можно скорее (возможно, после объявления о патче безопасности), а предыдущий взлом PHP-файлов мешает быстро исправить.
Однако не все параметры подвергаются экстернализации: на начальном этапе разработки, до реализации пользовательской истории, которая предписывает возможность конфигурации, произвольные функциональные параметры часто жестко кодируются. Это ни в коем случае не ограничение
на этапе разработки, поскольку последующие рефакторинги могут извлекать такие параметры, как размер кэша и имена папок, или принятые типы MIME для загрузки файлов.
Частным случаем, разрешенным в современных версиях PHP, является определение относительных путей. Благодаря операторам include () и require () относительные пути часто используются в файлах, отличных от того, который их создал.
Тем не менее, PHP предоставляет хитрость для автоматической настройки абсолютных путей: магическая константа __FILE__. Эта константа преобразуется в абсолютное имя файла каждого файла, в котором она содержится, что позволяет создавать однозначные абсолютные пути без жесткого кодирования:
<?php
echo dirname(__FILE__); // the directory which the file is in
echo realpath(dirname(__FILE__) . '/../'); // the parent directory
PHP 5.3 делает это дальше с магической константой __DIR__, которая по сути является сокращением для dirname (__ FILE__). Эти константы часто используются для настройки
include_path и позволяют сценариям ссылаться на путь относительно базовой папки приложения.
include_path зависит от сервера и подключается в php.ini в общих хостингах, поэтому его модификация с использованием абсолютных путей, генерируемых во время выполнения, является мощным решением.
Здесь я представлю стандартные носители для файлов конфигурации, используемые в приложениях PHP. В частности, эти форматы ориентированы на символы и строки, в результате чего получаются редактируемые человеком файлы. Тем не менее, существуют некоторые специфичные для домена файлы конфигурации, которые развертываются в двоичном виде, главным образом для целей производительности и интеграции, и ищут помощи внешних инструментов и компиляторов, таких как
gettext для локализации.
INI файлы
Хотя он традиционно ассоциируется с Windows, формат файла INI изначально поддерживается PHP и поддерживает сам бинарный дистрибутив: большая часть серверной конфигурации интерпретатора PHP содержится в файле php.ini.
Упомянутая поддержка обеспечивается
глобальной функцией parse_ini_file ():
// config.ini
[sectionName]
directive = value
// config_ini.php
<?php
$config = parse_ini_file('config.ini', true);
var_dump($config);
// result
array(1) {
["sectionName"]=>
array(1) {
["directive"]=>
string(5) "value"
}
}
Функции ini_get () и ini_set () связаны с переопределением директив php.ini (INItialization), а не с пользовательскими файлами INI.
XML-файлы
XML является языком общения между различными приложениями, и, хотя он многословен и критикуется, он действительно лучше, чем двоичные форматы, использовавшиеся в прошлом. PHP изначально поддерживает также синтаксический анализ файлов XML и их использование в целях конфигурации:
// config.xml
<?xml version="1.0"?>
<config>
<sectionName>
<directive>value</directive>
</sectionName>
</config>
// config_xml.php
<?php
$config = new SimpleXMLElement(file_get_contents('config.xml'));
var_dump($config);
// result
object(SimpleXMLElement)#1 (1) {
["sectionName"]=>
object(SimpleXMLElement)#2 (1) {
["directive"]=>
string(5) "value"
}
}
Расширение SimpleXML включено по умолчанию в PHP 5, поэтому оно должно быть доступно практически на каждом веб-сервере на Земле. XML не ограничивается конфигурацией, и знание SimpleXML также является хорошим дополнением к вашему инструментарию PHP. Вам даже не нужно определение схемы XML!
Родной PHP
Файлы PHP могут возвращать значение, когда они оцениваются с помощью include () или require (). Значение может состоять из любой допустимой переменной и, в частности, многомерного массива, который содержит конфигурацию (или более сложный объект):
// config.php
<?php
return array(
'sectionName' => array(
'directive' => 'value'
)
);
// config_php.php
<?php
$config = include 'config.php';
var_dump($config);
// result
array(1) {
["sectionName"]=>
array(1) {
["directive"]=>
string(5) "value"
}
}
This is dangerous as a syntax error may stop the execution of the client PHP scripts; however it is useful for avoiding dumb repetition and generate part of the configuration on the fly. This configuration won’t be usually human readable as the INI one. Beware of incorporating too much logic in configuration files: they are meant to separate custom settings from business logic, and throwing logic in them means you’re back to square one.
For a common object-oriented interface over INI and XML configuration files, check out Zend_Config, the component of Zend Framework dedicated to configuration management. You have seen in this article though that is very simple to parse configuration files with native PHP features.