Создание файла конфигурации в PHP
Я хочу создать файл конфигурации для своего проекта PHP, но я не уверен, что это лучший способ сделать это.
Пока у меня есть 3 идеи.
Переменная 1-Use
$config['hostname'] = "localhost";
$config['dbuser'] = "dbuser";
$config['dbpassword'] = "dbpassword";
$config['dbname'] = "dbname";
$config['sitetitle'] = "sitetitle";
2-Const Cona
define('DB_NAME', 'test');
define('DB_USER', 'root');
define('DB_PASSWORD', '');
define('DB_HOST', 'localhost');
define('TITLE', 'sitetitle');
База данных с 3-мя использованием
Я буду использовать конфиг в классах, поэтому я не уверен, какой путь будет лучшим или есть лучший.
Ответы
Ответ 1
Один простой, но элегантный способ - создать файл config.php
(или как вы его называете), который просто возвращает массив:
<?php
return array(
'host' => 'localhost',
'username' => 'root',
);
А потом:
$configs = include('config.php');
Ответ 2
Используйте INI файл - гибкое и мощное решение! PHP имеет встроенную функцию для правильной обработки. Например, можно создать файл INI следующим образом:
app.ini
[database]
db_name = mydatabase
db_user = myuser
db_password = mypassword
[application]
app_email = [email protected]
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']; // [email protected]
ВАЖНО: В целях безопасности файл INI должен находиться в непубличной папке
Ответ 3
Я использую небольшую эволюцию решения @hugo_leonardo :
<?php
return (object) array(
'host' => 'localhost',
'username' => 'root',
'pass' => 'password',
'database' => 'db'
);
?>
Это позволяет использовать синтаксис объекта при включении php: $configs->host
вместо $configs['host']
.
Кроме того, если ваше приложение имеет настройки на стороне клиента (например, для приложения Angular), вы можете иметь этот файл config.php
, содержащий все ваши конфиги (централизованные в одном файле вместо одного для JavaScript и один для PHP). Тогда трюк должен был иметь еще один PHP файл, в котором echo
была только информация о стороне клиента (чтобы не показывать информацию, которую вы не хотите показывать, как строка подключения к базе данных). Позвоните, скажите get_app_info.php
:
<?php
$configs = include('config.php');
echo json_encode($configs->app_info);
?>
Вышеприведенное предположение, что ваш config.php
содержит параметр app_info
:
<?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(...);
.
Ответ 4
Варианты, которые я вижу с относительными достоинствами/недостатками:
Файловые механизмы
Это требует, чтобы ваш код смотрел в определенных местах, чтобы найти INI файл. Это сложная проблема, которая всегда возникает в больших PHP-приложениях. Однако вам, вероятно, придется решить эту проблему, чтобы найти код PHP, который включается/используется повторно во время выполнения.
Обычные подходы к этому заключаются в том, чтобы всегда использовать относительные каталоги или осуществлять поиск в текущем каталоге и выше, чтобы найти файл с исключительно именем в базовом каталоге приложения.
Стандартные форматы файлов, используемые для конфигурационных файлов: PHP-код, ini-форматированные файлы, JSON, XML, YAML и сериализованный PHP
Код PHP
Это обеспечивает огромную гибкость для представления различных структур данных, и (при условии, что он обрабатывается с помощью функции include или require) проанализированный код будет доступен из кэша кода операции, что дает выигрыш в производительности.
include_path предоставляет средства для абстрагирования потенциальных местоположений файла без использования дополнительного кода.
С другой стороны, одной из основных причин ветки конфигурации от кода является разделение обязанностей. Он обеспечивает маршрут для добавления дополнительного кода в среду выполнения.
Если конфигурация создается из инструмента, может быть возможно проверить данные в инструменте, но нет стандартной функции для экранирования данных для встраивания в код PHP, которая существует для HTML, URL-адресов, операторов MySQL, команд оболочки....
Сериализованные данные
Это относительно эффективно для небольших объемов конфигурации (до 200 элементов) и позволяет использовать любую структуру данных PHP. Для создания/анализа файла данных требуется очень мало кода (поэтому вместо этого вы можете потратить свои усилия на то, чтобы файл записывался только с соответствующей авторизацией).
Экранирование содержимого, записанного в файл, обрабатывается автоматически.
Поскольку вы можете сериализовать объекты, это создает возможность для вызова кода, просто прочитав файл конфигурации (магический метод __wakeup).
Структурированный файл
Хранение его в виде INI файла, как предложено Marcel, JSON или XML, также предоставляет простой API-интерфейс для сопоставления файла со структурой данных PHP (и, за исключением XML, для экранирования данных и создания файла) при одновременном исключении вызова кода. уязвимость при использовании сериализованных данных PHP.
Он будет иметь такие же характеристики производительности, что и сериализованные данные.
Хранение базы данных
Это лучше всего рассматривать в тех случаях, когда у вас огромный объем конфигурации, но вы можете выбирать то, что нужно для текущей задачи - я был удивлен, обнаружив, что при 150 элементах данных было быстрее получить данные из локального экземпляра MySQL, чем десериализовать файл данных.
OTOH - не самое подходящее место для хранения учетных данных, которые вы используете для подключения к вашей базе данных!
Среда исполнения
Вы можете установить значения в среде исполнения, в которой работает PHP.
Это устраняет любое требование к коду PHP искать в определенном месте для конфигурации. OTOH плохо масштабируется для больших объемов данных, и его трудно изменить универсально во время выполнения.
На клиенте
Одно место, которое я не упомянул для хранения данных конфигурации, - это клиент. Снова сетевые издержки означают, что это плохо масштабируется до больших объемов конфигурации. А поскольку конечный пользователь имеет контроль над данными, они должны храниться в формате, в котором можно обнаружить любое вмешательство (т.е. с помощью криптографической подписи), и не должны содержать никакой информации, которая может быть скомпрометирована их раскрытием (то есть обратимо зашифровано).
И наоборот, это имеет много преимуществ для хранения конфиденциальной информации, которой владеет конечный пользователь - если вы не храните ее на сервере, ее нельзя оттуда украсть.
Сетевые каталоги
Еще одно интересное место для хранения информации о конфигурации находится в DNS/LDAP. Это будет работать для небольшого количества небольших фрагментов информации - но вам не нужно придерживаться первой нормальной формы - рассмотрите, например, SPF.
Инфраструктура поддерживает кэширование, репликацию и распространение. Следовательно, он хорошо работает для очень больших инфраструктур.
Системы контроля версий
Конфигурация, как и код, должна управляться и контролироваться версией - следовательно, получение конфигурации непосредственно из вашей системы VC является жизнеспособным решением. Но часто это приводит к значительному снижению производительности, поэтому рекомендуется использовать кэширование.
Ответ 5
Хорошо - было бы сложно хранить данные конфигурации базы данных в базе данных - не так ли?
Но на самом деле, это довольно сильно упрямый вопрос, потому что любой стиль действительно работает, и все это зависит от предпочтений. Лично я бы выбрал переменную конфигурации, а не константы - вообще, потому что мне не нравятся вещи в глобальном пространстве, если это необходимо. Ни одна из функций моей кодовой базы не должна иметь возможности легко получить доступ к моему паролю базы данных (кроме моей логики подключения к базе данных), поэтому я бы использовал его там, а затем, вероятно, уничтожил его.
Изменить: чтобы ответить на ваш комментарий - ни один из механизмов синтаксического анализа не был бы самым быстрым (ini, json и т.д.), но они также не являются частью вашего приложения, необходимо сосредоточиться на оптимизации, поскольку разница в скорости будет незначительной на таких небольших файлах.
Ответ 6
Определить сделает константу доступной везде в вашем классе без необходимости использовать глобальную, в то время как переменная требует глобального класса, я бы использовал DEFINE. но опять же, если параметры db должны меняться во время выполнения программы, вы можете захотеть придерживаться переменной.
Ответ 7
Если вы думаете, что по какой-то причине вы будете использовать более 1 дБ, перейдите к переменной, потому что вы сможете изменить один параметр, чтобы переключиться на совершенно другой db. То есть для тестирования, autobackup и т.д.
Ответ 8
Вы можете создать статические свойства класса класса конфигурации
class Config
{
static $dbHost = 'localhost';
static $dbUsername = 'user';
static $dbPassword = 'pass';
}
то вы можете просто использовать его:
Config::$dbHost
Иногда в моих проектах я использую шаблон проектирования SINGLETON для доступа к данным конфигурации. Это очень удобно в использовании.
Почему?
Например, у вас есть 2 источника данных в вашем проекте. И вы можете выбрать, что ведьма из них включена.
Где-то в файле конфигурации вы выбираете:
$dataSource = 'mysql' // or 'json'
Когда вы меняете исходное целое приложение shoud на новый источник данных, работайте нормально и не нуждаетесь в изменении кода.
Пример:
Config:
class Config
{
// ....
static $dataSource = 'mysql';
/ .....
}
Класс Singleton:
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 и создание нового объекта определенного класса источника данных. Теперь наш script может получить объект и работать на нем, не зная
даже какая конкретная реализация действительно существует.
Ответ 9
Обычно я создаю единственный файл conn.php с моими подключениями к базе данных.
Затем я включаю этот файл во все файлы, требующие запросов к базе данных.
Ответ 10
Вот мой путь.
<?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";
? >
Любые сомнения, пожалуйста, прокомментируйте