Mr.KTO blog

Формат конфигурационных файлов

Здесь речь пойдёт о пользовательских конфигурационных файлах. То есть файлах, где хранятся настройки текущего проекта, которые скрипт тем или иным образом извлекает и использует, а администратор системы может изменять. Сегодня мы сравним типы конфигов и узнаем какой для чего использовать лучше.

Сначала то, о чём все знают, потом – мой способ хранения конфигов!

  1. Использование PHP
    config.inc
    <?php
    define("DB_HOST", "localhost");
    # также здесь возможны комментарии
    $sitehost = "www.site.com";
    $cfg['session_len'] = 30*60*60; // можно использовать результат вычислений
    ?>    
    
    использование:
    require("conf/config.inc");
    echo $sitehost;
    echo $cfg['session_len'];
    echo DB_HOST;
    

    Преимущества:

    • К константам/переменным можно обратится сразу по имени.
    • Быстрота получения данных из конфига (т.к. обрабатывается обычный код PHP)

    Недостатки:

    • Использование глобальных переменных в ООП-приложении нежелательно, а сделать все настройки константами - не лучший вариант.
    • Для людей, незнакомых с PHP - ошибки при модификации файла, изменении настроек.
  2. Использование XML
    config.xml
    <db>
        <host>localhost</host>
        <user>user123</user>
        <pass>qwerty</pass>
        <dbname>mydb</dbname>
    </db>
    
    использование:
    $conf = simplexml_load_file("conf/config.xml");
    $db_name = $conf->dbname;
    

    Преимущества:

    • Здесь не будет ошибок PHP
    • Это модно

    Недостатки:

    • Необходимо хорошо знать XML, чтобы не допустить ошибок, например служебные символы (напр. <>&)
    • Редактировать/читать такой файл (особенно когда он большой) очень сложно без специального редактора, также нет возможности писать комментарии
    • Совместимо только с PHP 5 (для php 4 нужны нестандартные модули/функции)
  3. Использование INI-файлов
    config.ini
    ; в ini-файлах возможны такие комментарии
    [database]
    db_host = localhost
    db_name = dbabc
    ; также возможно разделение по разделам
    [site]
    site_host = "host.com"
    
    использование:
    $conf = parse_ini_file("conf/config.ini", true);
    $db_name = $conf['database']['db_name'];
    

    Преимущества:

    • Простой формат, используется для конфигурации PHP, MySQL, BSD/*nix-систем
    • Т.к. parse_ini_file возвращает ассоциативный массив с разделами ( , true); ) - это удобно для установки свойств основного класса системы, или той же глобальной переменной $cfg

    Недостатки:

    • Хотя ini-формат и поддерживает строки с использованием двойных кавычек (для возможности поставить = в значении), но в PHP 4 многострочные значения невозможны. Невозможно экранирование двойной кавычки.
    • Парсинг ini-файлов, даже при испольовании встроенной в PHP функции происходит медленно. Т.к. использование конфига необходимо на каждой страничке - то для посещаемых сайтов надо использовать кэширование в формат php.
  4. Моё предложение

    Основано на поддержке return-а в include-файлах.

    config.inc
    <?php
    return array(
    
        "phone_regex" => '/^[0-9 ,+\(\)]{3,30}$/', // коментарий здесь 
    
        "text" => "любые символы: \x20@\x44\x66 ss \" ' ff " .
                  "и перенос через сложение строк",
    
        "bigtext" => <<<HEREDOC
    какой-то текст здесь
    и может быть: "  "  ''  '
    т.к. это heredoc
    HEREDOC
    ,
         "any" => 0x112, // число в hex
    
         "int" => 5*60; // вычисления
    
    #     "key" => "val", // закоментирована строка 
    
          "db" => array(
                        "name" => "db1",
                        "user" => "db_user1",
                       ),
    );
    ?>
    
    использование:
    $conf = require("conf/config.inc");
    $db_name = $conf['database']['db_name'];
    

    Преимущества:

    • Вполне понятный формат. В конце концов, для неподготовленного пользователя - можно сделать скрипт настройки с проверкой верности данных, после чего результат компилируется в мой формат.
    • Быстрота выполнения
    • Нет инициализации глобальных переменных, вы сами решаете какие переменные/свойства будут иметь эти значения
    • Совместимо с php4/5, возможно использовать любые значения, в т.ч. вычисление, перенос строк через сложение.
    • Если в папке config не запрещено чтение файлов, то при вызове server/config.ini будут выведены все настроки, а здесь - нет

Добавление: Пример изменения конфига:

function save_config($fname, $cfg = array())
{
	$s = "<?php\r\nreturn array(\r\n";
	foreach($cfg as $name => $value) { // можно ещё добавить поддержку $value как массив
		$name  = str_replace('"', '\\"', $name);  // экранировать двойную кавычку
		$value = str_replace('"', '\\"', $value); // (можно доб. и др. символы)
		$s .= "\t\"$name\" => \"$value\",\r\n";
	}
	$s .= ");\r\n?>";
	if (false === $f = fopen($fname, "w")) return false;
	fwrite($f, $s);
	fclose($f);
	return true;
}

$cfg = require("inc/config.inc");
$cfg['db_user'] = "user123";

save_config("inc/config.inc", $cfg);
habrahabr.ru google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru rumarkz.ru memori.ru moemesto.ru moikrug.ru myscoop.ru mister-wong.ru rucity.com vaau.ru

Комментарии (2) на “Формат конфигурационных файлов”

  1. izra.ru пишет:

    mrkto, по поводу 5-го преимущества в твоем варианте. Все служебные файлы, доступ к которым можно получать только из под php кладу в папку, которая содержит в названии #.

  2. polygon пишет:

    свое мнение о последнем способе написал в http://kmsays.livejournal.com/6881.html

Оставить комментарий