Я часто переключаюсь между .NET и PHP. С сайтами ASP.NET я сохраняю информацию о конфигурации (например, строки подключения, каталоги, параметры приложения) в файле web.config, который надлежащим образом защищен и легко доступен для значений и т. Д.
В PHP я решаю это с классом, который имеет статические методы для каждой переменной:
class webconfig { public static function defaultPageIdCode() { return 'welcome'; } }
Файл, включенный в переменные приложения, доступен с помощью одной строки:
$dp = webconfig::defaultPageIdCode();
И поскольку PHP не скомпилирован, в любом случае легко подключиться к telnet и изменить значение для веб-сайта, поэтому это решение работает достаточно хорошо и дает мне следующие два преимущества :
Но я могу представить себе, что есть другие способы решения проблемы сохранения настроек веб-конфигурации в PHP, которые могут иметь другие преимущества.
Особенно те, кто имеет опыт работы с несколькими фреймворками PHP, каковы другие способы сохранения конфигурационных переменных и их преимуществ и недостатков?
Я решил перечислить все известные методы вместе с их преимуществами и недостатками.
Я отметил этот ответ в качестве вики-сообщества, поэтому сотрудничество стало проще.
define('CONFIG_DIRECTIVE', 'value');
$object = new MyObject(CONFIG_DIRECTIVE);
Например: XML, INI, YAML и т. Д.
config_directive = value
.) parse_ini_file()
.) $config['directive'] = 'value';
$object = new MyObject($config['directive']);
$container = new MyContainer($config);
myCfgObj::setDirective('DIRECTIVE', 'value');
myCfgObj->setDirective('DIRECTIVE', 'value');
$object = new MyObject(myCfgObj::getDirective('DIRECTIVE'));
$object = new MyObject(myCfgObj->getDirective('DIRECTIVE'));
Я обычно использую статический класс Settings в PHP, это потому, что
Пример:
abstract class Settings { static private $protected = array(); // For DB / passwords etc static private $public = array(); // For all public strings such as meta stuff for site public static function getProtected($key) { return isset(self::$protected[$key]) ? self::$protected[$key] : false; } public static function getPublic($key) { return isset(self::$public[$key]) ? self::$public[$key] : false; } public static function setProtected($key,$value) { self::$protected[$key] = $value; } public static function setPublic($key,$value) { self::$public[$key] = $value; } public function __get($key) {//$this->key // returns public->key return isset(self::$public[$key]) ? self::$public[$key] : false; } public function __isset($key) { return isset(self::$public[$key]); } }
Затем в пределах вашей среды выполнения, если вы сначала загрузили этот файл, а затем ваш файл конфигурации базы данных, ваш файл конфигурации базы данных выглядел бы так:
<?php Settings::setProtected('db_hostname', 'localhost'); Settings::setProtected('db_username', 'root'); Settings::setProtected('db_password', ''); Settings::setProtected('db_database', 'root'); Settings::setProtected('db_charset', 'UTF-8'); //... echo Settings::getProtected('db_hostname'); // localhost //... Settings::setPublic('config_site_title', 'MySiteTitle'); Settings::setPublic('config_site_charset', 'UTF-8'); Settings::setPublic('config_site_root', 'http://localhost/dev/');
Поскольку вы можете видеть, что у нас есть метод __get
, которому разрешено допускать публичные переменные, пример того, почему мы имеем это, выглядит следующим образом:
$template = new Template(); $template->assign('settings', new Settings());
Независимо от того, что мы использовали этот объект как статический объект, значения должны оставаться в пределах шаблона, который вы теперь можете сделать, скажем.
<html> <head> <?php echo isset($settings->config_site_title) ? $settings->config_site_title : 'Fallback Title'; ?> </head> </html>
И это позволит вам иметь доступ к общедоступным данным в течение инициализированного периода.
Это может стать намного более сложным, но более системным, а некоторые примеры:
loadConfig
для автоматического анализа файла конфигурации, xml, php, yaml. shutdown_function
вы можете автоматически обновить базу данных новыми настройками. Это тоже я, безусловно, лучший способ завершить эту работу.
То, как я это делаю, прямо хранит их в array
и сохраняет файл как config.php
<?php $config['dbname'] = "mydatabase"; $config['WebsiteName'] = "Fundoo Site"; $config['credits'] = true; $config['version'] = "4.0.4"; ?>
Thi – это способ большинства PHP-фреймворков, таких как WordPress и т. Д.
Примечание: «Лучший способ» никогда не существует. Каждое приложение и каркас делают свой стиль. Пока ваш пример делает трюк, я думаю, что он немного ресурсоемкий для простого конфигурационного файла.
Редактировать:
Эдвард, пожалуйста, взгляните на примеры parse_ini_file. Вы можете загрузить файл .ini с помощью простой команды, тогда вы можете использовать переменные в классе, как в вашем примере.
Есть много возможностей, которые я думаю, но наиболее распространенные методы хранятся в виде обычного текста в таких файлах, как .csv, .ini, .xml. С небольшими трюками вы можете защитить эти файлы, чтобы никто не мог напрямую загружать файлы.
пример INI-файла:
;<?php die(); ?> [config1] var1 = 'value1'; var2 = 'value2'; ... [config2] ...
;
считается комментарием в ini-файлах. Поэтому, когда вы читаете файл с помощью ini-parser, эта строка будет проигнорирована. Если кто-то обратится к файлу напрямую через url, будет выполняться функция die()
. Это работает только, если INI-файл носит расширение файла, например .php, чтобы сервер знал, что это должно выполняться, а не дублироваться как обычный текст.
Возможным недостатком большинства файловых баз-конфигурационных хранилищ являются проблемы с некоторыми utf8-символами.
Zend_Config является компонентом Zend-Framework, который предоставляет возможности для нескольких адаптеров хранения с простым в использовании api.
В PHP я всегда использую «.htaccess» для защиты моего файла конфигурации (двойная защита)
Поскольку PHP способен использовать OO, мне нравится идти с «классом конфигурации»:
class Config { /** * --------------------------------- * Database - Access * --------------------------------- */ /** * @var String */ const DB_DRIVER = 'pgsql'; const DB_USER = 'postgres'; const DB_PASSWORD = 'postgres'; const DB_NAME = 'postgres'; }
Его легко получить с помощью Config :: DB_DRIVER. Не нужно включать файл, так как автозагрузчик приложений сделает это за вас. Конечно, защита файла еще должна быть выполнена.
Telnet? OMG Я попал в timewarp и прибыл в 1992 году!
Но серьезно, IIRC есть инструменты, которые позволяют asp.net (и другим языкам) анализировать данные сеанса – это всего лишь сериализованный php-массив. Я бы попытался реализовать глобальные настройки как своего рода теневую сессию в PHP. Даже если вы не храните свои настройки конфигурации в виде сериализованного массива PHP, вы можете отобразить их в сеансе во время выполнения, используя собственный обработчик сеанса.
С точки зрения того, где вы храните данные – это более сложно, когда вы предположительно работаете на платформе Microsoft. Очевидно, что вы не хотите, чтобы расходы на доступ к диску для каждого запроса. Хотя NT делает некоторое кэширование диска, это не так (IME) настолько же эффективно, как и другие ОС. Memcached – это одно из решений. Кажется, он доступен из asp.net.
НТН
Обычный маршрут – использовать define
:
define('MYSQL_USER', 'ROOT');
и получить доступ ко всем приложениям через MYSQL_USER
:
$user = MYSQL_USER;
Однако массивы не поддерживаются таким образом.
Есть несколько возможностей:
Вы можете использовать конфигурационный файл (ini, json, xml или yaml). Для ini у вас есть parse_ini_file
, для JSON есть json_decode
(+ file_get_contents), для YAML вам нужно использовать внешнюю библиотеку (поиск sfYaml)
У вас может быть файл конфигурации с переменными или константами (лучше для неизменяемой конфигурации и доступен во всех областях), которые вы включаете в свой скрипт:
define ('ROOT_DIR', '\ home \ www');
$ sRootDir = '\ home \ www';
Если вы ориентированы на OO, вы можете обернуть его в класс, как свойства – у вас нет метода getter для каждого свойства, вы можете просто иметь:
class Config { public $var1 = 'xxx'; public $var2 = 'yyy'; }
($ c = new Config (); print $ c-> var1)
или
static class Config { public static $var1 = 'xxx'; public static $var2 = 'yyy'; }
(print c :: $ var1)
Лучше всего иметь класс типа реестра, реализующий singleton pattern и способный читать конфигурацию из данного файла.
Для проверки можно использовать класс Config
который содержит фактические данные конфигурации и статический класс AppConfig
который содержит ссылку на объект Config
загруженный при загрузке из файлов конфигурации приложения (зависимость, введенная при загрузке). В среде тестов я изменяю только объект Config
. См. https://github.com/xprt64/Config