Хранилище конфигурации PHP

способы хранения конфигурации для веб-приложения, написанного на PHP?
Я видел, как люди используют .ini, basic .PHP и др.
Кроме того,define() или просто глобальные переменные?
Большинство информации, как вы можете найти.
Кроме того, являются ли базы данных хорошими методами хранения конфигурации?

7 ответов


нет " лучшего способа (tm)" для хранения конфигураций приложений. На самом деле все зависит от вашего приложения, вида конфигураций, как часто они могут/должны меняться и как легко вы хотите их изменить.

некоторые люди используют полный синглтон (или статический) Config класс для приложения. Что выглядит примерно так (с различными уровнями сложности):

<?php

class Config
{

    protected static $config = array();

    private function __construct() {} // make this private so we can't instanciate

    public static function set($key, $val)
    {
        self::$config[$key] = $val;
    }

    public static function get($key)
    {
        return self::$config[$key];
    }

}

это удобно, потому что вы можете называть его везде, где вы хотите в вашем применение с Config::set() или Config::get(). Затем у вас есть центральное место, которое настроено все ваше приложение, и вы можете сделать его сложным или простым, как вам нравится. Вы можете создавать резервные копии в базе данных, memcached и т. д.

что подводит меня к следующему. Использование базы данных отлично подходит для вещей, которые должны быть изменены на лету и не обязательно должны иметь "начальную настройку". Примером могут служить функции настройки приложения сайта (например. валюта, цвет фона, изображение заголовка и т. д.). Проблема здесь в том, что вы должны загружать это каждый раз, когда страница загружается в ваше приложение. Чтобы решить эту проблему, вы можете использовать технологию кэширования среднего слоя (например, memcached, если хотите). Это было бы быстро, намного быстрее, чем база данных, но все равно добавляет накладные расходы, потому что вы должны загружать ее при каждой загрузке страницы.

самый быстрый способ и, следовательно, самый "трудный" для изменения-использовать config.php файл или тому подобное. Этот файл $_GLOBALS определения ключей массива или define()для значений, к которым вам нужен доступ во всем вашем приложении. Это быстро, потому что он включен в запрос и жестко закодирован в PHP, поэтому все, что PHP должен сделать, это интерпретировать файл - нет сетевого ввода-вывода или каких-либо дополнительных накладных расходов, кроме минимальных накладных расходов на включение файла в ваш скрипт. То, что вы храните в этих файлах PHP, - это такие вещи, как учетные данные подключения MySQL, учетные данные подключения к веб-службе и т. д.

для приложение, которое имеет много пользователей и много настроек, вам, вероятно, придется развернуть "гибрид" методов или придумать свой собственный. Для чего-то, что является просто стандартным развертыванием приложения, вы можете уйти с очень простым config.php тип подхода.


Я не думаю, что есть лучший способ, каждый способ имеет свои преимущества и недостатки. Просто убедитесь, что файл конфигурации (особенно если она содержит пароли)недоступно в общедоступном каталоге, но где-то в частном.

сохранение конфигурации в базе данных может работать, но вам все равно нужно будет сохранить информацию о подключении к базе данных где-то, чтобы получить соединение. Лично я никогда не был поклонником этого метода. Единственное преимущество легко онлайн изменять значения элементов конфигурации или иметь конфигурацию на уровне пользователя, например.

С помощью define(); создаст константы, значение которых нельзя изменить во время выполнения. В одних случаях это работает, в других-нет. Если вы хотите, чтобы ваша конфигурация была доступна везде - в каждой области-вы могли бы рассмотреть возможность чтения конфигурации в класс (возможно, одноэлементный шаблон?) чтобы вы могли получить доступ к значениям конфигурации повсюду.

я использовал включенный php-файл .ini-файлы, XML-файлы и JSON-файлы для настройки, лично я предпочитаю избегать .файлы конфигурации php, поскольку я делюсь своими файлами конфигурации между несколькими языками для разных приложений в моих веб-приложениях и придерживаюсь других "стандартов".


.ini не является хорошим способом хранения конфигураций, так как веб-сервер будет отображать его публично. Не делай этого.

хранить конфиги на .PHP-файл. Вы можете использовать глобальные переменные, функции define() или обычные переменные. Define обычно лучше всего подходит. Для большей безопасности поместите его вне общедоступного каталога.

обычно я размещаю настройки базы данных в config.php и все динамические настройки в базе данных. Все настройки, которые не сильно меняются, обычно хороши для размещения конфигурационный файл. Как пути и т. д.


как на самом деле @ Roger Ng указал, принятый ответ на самом деле не работает. Проблема в том, что вы не можете использовать $this в статическом методе.
PHP: Ключевое слово Static-Manual

Я думал об этом следующим образом:

class Config {
    protected static $config=array();
    private function __construct(){}
    public static function set($k,$v){
            self::$config[$k]=$v;
    }
    public static function get($k){
            return self::$config[$k];
    }
    public static function init($a){
            self::$config=$a;
    }
    public static function merge($a){
            self::$config=array_merge(self::$config,$a);
    }
}

Я использую функцию Config::init() создать настройки по умолчанию, чтобы вернуться к, и Config::merge() функция для объединения конфигураций по умолчанию с, например, производственными значениями.

так вот мой default_config.php может выглядеть следующим образом:

Config::init(array(
    'key' => 'value',
    'key2' => 'value2',
));

и мой конфиг.php что-то вроде следующего:

Config::merge(array(
    'key' => 'newvalue',
    'key3' => 'value3',
));

в фактическом коде я получу свои значения конфигурации точно так же, как это сделано в принятом ответе, написав Config::get('key').


IMO, сегодня имеет смысл хранить ваши данные конфигурации в файле JSON.

некоторые преимущества JSON:

  • родная поддержка на многих языках программирования
  • легко читать для людей
  • легко читать для машин
  • малый размер файла

пример кода :

файл Json:

{
    "version" : "0.0.1",
    "title" : "My first web app",
    "database" : {
        "host" : "localhost",
        "name" : "DB",
        "user" : "JJ",
        "password" : "Passw0rd"
    }
}

класс PHP :

namespace App;

class Config {

    protected static $config = array();

    public static function load($filename) {
        static::$config = json_decode(file_get_contents($filename), true);
    }

    [...]
}

загрузка файла Json:

\App\Config::load('myConfigFile.json');

это то, что я делаю.

во-первых, я определяю общий Dataset класс, который я могу использовать для глобального хранилища данных :

<?php

namespace MyNamespace\Core;

class Dataset {

    protected static $_data = array();

    public static function set($key, $value) {
        static::$_data[$key] = $value;
    }

    public static function get($key) {
        return static::$_data[$key];
    }

    public static function remove($key) {
        unset(static::$_data[$key]);
    }
}
?>

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

<?php

namespace MyNamespace\Core;

class Config extends Factory {

    protected static $_data = array();

}
?>

обратите внимание, что важно добавить правило protected static $_data = array(); до Config class или любые другие дочерние классы, если вы не хотите, чтобы они разделяли один и тот же массив.


Я изменил код James & Zachu. Вот моя реализация. При поиске значения и при его наличии возвращается пустая строка. Таким образом, никаких уведомлений не будет. Существует метод delete. комментарии и форматирование кода.

<?php
/*
 * This file can be used to store config values. It is based on discussion below.
 * @see https://stackoverflow.com/questions/5923778/php-configuration-storage
 * @author https://stackoverflow.com/users/2632129/james
 * @author https://stackoverflow.com/users/3173125/zachu
 * @author Slavi Marinov | http://orbisius.com
 */
class App_Config {
    protected static $config = array();

    /**
     * Do not instantiate this class
     */
    private function __construct() {}

    /**
     * Initializes or resets the config if nothing is supplied
     * App_Config::init();
     * @param array $a
     */
    public static function init($a = array()) {
        self::$config = $a;
    }

    /**
     * App_Config::get();
     * @param str $k
     * @return mixed
     */
    public static function get($k) {
        return empty(self::$config[$k]) ? '' : self::$config[$k];
    }

    /**
     * Sets a value
     * App_Config::set();
     * @param str $k
     * @param mixed $v
     */
    public static function set($k, $v) {
        self::$config[$k] = $v;
    }

    /**
     * Removes a key
     * App_Config::remove();
     * @param str $k
     * @param mixed $v
     */
    public static function remove($k) {
        unset(self::$config[$k]);
    }

    /**
     * Removes a key
     * App_Config::delete();
     * @param str $k
     * @param mixed $v
     */
    public static function delete($k) {
        self::remove($k);
    }

    /**
     * App_Config::exists();
     * @param str $k
     * @return bool
     */
    public static function exists($k) {
        return isset(self::$config[$k]) ? true : false;
    }

    /**
     * App_Config::merge();
     * @param str $k
     * @return array
     */
    public static function merge($a) {
        self::$config = array_merge(self::$config, $a);
        return self::$config;
    }
}