Создание файла конфигурации в PHP

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

у меня есть 2 идеи до сих пор.

1-Использовать Переменную

$config['hostname'] = "localhost";
$config['dbuser'] = "dbuser";
$config['dbpassword'] = "dbpassword";
$config['dbname'] = "dbname";
$config['sitetitle'] = "sitetitle";

2-Используйте Const

define('DB_NAME', 'test');
define('DB_USER', 'root');
define('DB_PASSWORD', '');
define('DB_HOST', 'localhost');
define('TITLE', 'sitetitle');

3-Использовать Базу Данных

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

10 ответов


один простой, но элегантный способ создать config.php файл (или как вы его называете), который просто возвращает массив:

<?php

return array(
    'host' => 'localhost',
    'username' => 'root',
);

и затем:

$configs = include('config.php');

использование INI-файла-это гибкое и мощное решение! В PHP собственная функция правильно ее обрабатывать. Например, можно создать INI-файл следующим образом:

[database]
db_name     = mydatabase
db_user     = myuser
db_password = mypassword

[application]
app_email = mailer@myapp.com
app_url   = myapp.com

поэтому единственное, что вам нужно сделать, это вызов:

$ini = parse_ini_file('app.ini');

тогда вы можете легко получить доступ к определениям, используя $ini массив.

echo $ini['db_name'];     // mydatabase
echo $ini['db_user'];     // myuser
echo $ini['db_password']; // mypassword
echo $ini['app_email'];   // mailer@myapp.com

важно: по соображениям безопасности INI-файл должен находиться не в общей папке


Я использую небольшую эволюцию @hugo_leonardo ' s решение:

<?php

return (object) array(
    'host' => 'localhost',
    'username' => 'root',
    'pass' => 'password',
    'database' => 'db'
);

?>

это позволяет использовать синтаксис объекта при включении php:$configs->host вместо $configs['host'].

кроме того, если ваше приложение имеет необходимые конфигурации на стороне клиента (например, для углового приложения), вы можете иметь это config.php файл содержит все ваши конфигурации (централизованные в одном файле вместо одного для JavaScript и одного для PHP). Тогда трюк будет иметь другой файл PHP что бы echo только информация на стороне клиента (чтобы не показывать информацию, которую вы не хотите показывать как строку подключения к базе данных). Назовите это say get_app_info.php :

<?php

    $configs = include('config.php');
    echo json_encode($configs->app_info);

?>

выше предполагая, что ваш config.php содержит элемент :

<?php

return (object) array(
    'host' => 'localhost',
    'username' => 'root',
    'pass' => 'password',
    'database' => 'db',
    'app_info' => array(
        'appName'=>"App Name",
        'appURL'=> "http://yourURL/#/"
    )
);

?>

таким образом, информация о вашей базе данных остается на стороне сервера, но информация о вашем приложении доступна из вашего JavaScript, например $http.get('get_app_info.php').then(...); тип вызова.


Я довольно удивлен принятым ответом здесь и количеством полученных ответов. За исключением ответа Марсио Маццукато, не обсуждаются относительные достоинства / недостатки любого из многочисленных подходов.

варианты, которые я вижу:

механизмы

Они требуют, чтобы ваш код искал в определенных местах, чтобы найти ini-файл. Это трудная проблема, которую нужно решить и которая всегда появляется в больших приложениях PHP. Однако вам, вероятно, придется решить проблему, чтобы найти PHP-код, который будет включен / повторно использован во время выполнения.

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

общие форматы файлов, используемые для конфигурационных файлов: PHP-код, ini-файлы, JSON, XML, YAML и сериализованные В PHP

PHP-кода

Это обеспечивает огромную гибкость для представления различных структур данных, и (предполагая, что он обрабатывается через include или require) анализируемый код будет доступен из кэша кода операции, что дает преимущество в производительности.

на в include_path предоставляет средство для абстрагирования потенциальных местоположений файла без использования дополнительного кода.

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

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

сериализованные данные Это относительно эффективно для малых объем конфигурации (до 200 элементов) и позволяет использовать любую структуру данных PHP. Для создания / анализа файла данных требуется очень мало кода (поэтому вы можете потратить свои усилия на обеспечение того, чтобы файл был написан только с соответствующей авторизацией).

экранирование содержимого, записанного в файл, обрабатывается автоматически.

поскольку вы можете сериализовать объекты, это создает возможность для вызова кода просто путем чтения файла конфигурации (the __wakeup magic method).

структурированный файл

сохранение его в виде INI-файла, как предложено Марселем или JSON или XML, также предоставляет простой api для отображения файла в структуру данных PHP (и за исключением XML, чтобы избежать данных и создать файл), устраняя уязвимость вызова кода с помощью сериализованных данных PHP.

Он будет иметь аналогичные характеристики для сериализованных данных.


Ну - было бы сложно хранить данные конфигурации базы данных в базе данных - не так ли?

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

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


обычно я в конечном итоге создаю один conn.php-файл с подключениями к базе данных. Затем я включаю этот файл во все файлы, требующие запросов к базе данных.


Define сделает константу доступной везде в вашем классе без необходимости использовать global, в то время как переменная требует global в классе, я бы использовал DEFINE. но опять же, если параметры БД должны изменяться во время выполнения программы, вы можете придерживаться переменной.


Если вы думаете, что по какой-либо причине будете использовать более 1 дБ, перейдите к переменной, потому что вы сможете изменить один параметр, чтобы переключиться на совершенно другую дБ. Т. е. для испытывать, autobackup, etc.


вы можете создать статические свойства ведьмы класса конфигурации

class Config 
{
    static $dbHost = 'localhost';
    static $dbUsername = 'user';
    static $dbPassword  = 'pass';
}

затем вы можете просто использовать это:

Config::$dbHost  

иногда в моих проектах я использую шаблон дизайна SINGLETON для доступа к данным конфигурации. Он очень удобен в использовании.

почему?

например у вас есть 2 источника данных в проекте. И ты можешь выбрать ведьму из них включен.

  • в MySQL
  • в JSON

где-то в конфигурационном файле вы выбираете:

$dataSource = 'mysql' // or 'json'

при изменении источника всего приложения shoud переключиться на новый источник данных, работать нормально и не нужно менять код.

пример:

Config:

class Config 
{
  // ....
  static $dataSource = 'mysql';
  / .....
}

Синглтон-класс:

class AppConfig
{
    private static $instance;
    private $dataSource;

    private function __construct()
    {
        $this->init();
    }

    private function init()
    {
        switch (Config::$dataSource)
        {
            case 'mysql':
                $this->dataSource = new StorageMysql();
                break;
            case 'json':
                $this->dataSource = new StorageJson();
                break;
            default:
                $this->dataSource = new StorageMysql();
        }
    }

    public static function getInstance()
    {
        if (empty(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function getDataSource()
    {
        return $this->dataSource;
    }
}

... и где-то в коде (например. в каком-то сервисном классе):

$container->getItemsLoader(AppConfig::getInstance()->getDataSource()) // getItemsLoader need Object of specific data source class by dependency injection

мы можем получить AppConfig объект из любого места в системе и всегда получает одну и ту же копию (благодаря статике). Вызывается метод init () класса В конструкторе, который гарантирует только одно выполнение. Init () проверка кузова Значение config $dataSource и создать новый объект определенного класса источника данных. Теперь наш скрипт может получить объект и работать на нем, не зная даже какая конкретная реализация реально существует.


вот мой путь.

<?php

define('DEBUG',0);

define('PRODUCTION',1);



#development_mode : DEBUG / PRODUCTION

$development_mode = PRODUCTION;



#Website root path for links

$app_path = 'http://192.168.0.234/dealer/';



#User interface files path

$ui_path = 'ui/';

#Image gallery path

$gallery_path = 'ui/gallery/';


$mysqlserver = "localhost";
$mysqluser = "root";
$mysqlpass = "";
$mysqldb = "dealer_plus";

?>

любые сомнения, пожалуйста, прокомментируйте