我经常在.NET和PHP开发之间切换。使用 ASP.NET站点,我在 web.config 文件中保存配置信息(例如连接字符串,目录,应用程序设置),该文件受到适当保护并且易于访问值,等
在 PHP 中,我使用每个变量的类具有静态方法解决此问题:
class webconfig {
public static function defaultPageIdCode() {
return 'welcome';
}
}
应用变量的文件包含是通过一行访问的:
$dp = webconfig::defaultPageIdCode();
由于PHP未编译,因此很容易 telnet 并更改网站的值,因此此解决方案运行良好并给我这些两个优点:
但我可以想象,人们可以通过其他方式解决在PHP中保存Web配置设置的问题,这可能还有其他优势。
特别是那些有许多PHP框架经验的人,还有其他保存配置变量的方法及其优缺点?
答案 0 :(得分:36)
我决定列出所有已知的方法及其优点和缺点。
我已将此答案标记为社区维基,因此协作更容易。
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'));
答案 1 :(得分:23)
我倾向于在PHP中使用Settings静态类,这是因为
示例:
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
,则可以使用新设置自动更新数据库。这也是我迄今为止完成这项工作的最佳方法。
答案 2 :(得分:5)
我这样做是直接将它们存储在array
中并将文件另存为config.php
<?php
$config['dbname'] = "mydatabase";
$config['WebsiteName'] = "Fundoo Site";
$config['credits'] = true;
$config['version'] = "4.0.4";
?>
这是大多数PHP框架如Wordpress等的方式。
答案 3 :(得分:2)
注意:“最佳方式”永远不存在。每个应用程序和框架都以自己的风格完成。虽然你的例子正在做诀窍,但我认为对于一个简单的配置文件来说它有点资源。
修改强>
Edward请看一下parse_ini_file的例子。您可以使用简单的命令加载.ini文件,然后您可以在类中使用变量,就像您的示例中一样。
答案 4 :(得分:2)
我认为有很多可能性,但最常见的方法是将文本存储为.csv,.ini,.xml等文件。通过一些小技巧,您可以保护这些文件,这样任何人都无法直接加载文件。
INI-File示例:
;<?php die(); ?>
[config1]
var1 = 'value1';
var2 = 'value2';
...
[config2]
...
;
被视为ini文件中的评论。因此,当您使用ini-parser读入文件时,此行将被忽略。如果有人通过url直接访问该文件,则会执行die()
- 函数。这仅适用于INI文件使用.php等文件扩展名,以便服务器知道应该执行此操作而不是以纯文本形式显示。
大多数file-base-config-storage的可能缺点是某些utf8字符存在问题。
Zend_Config是Zend-Framework的一个组件,它为多个存储适配器提供了易于使用的API的可能性。
答案 5 :(得分:1)
在PHP中,我总是使用“.htaccess”来保护我的配置文件(双重保护)
答案 6 :(得分:1)
由于PHP能够使用OO,我喜欢使用“Config类”:
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可以轻松访问。无需包含该文件,因为应用程序自动加载器将为您执行此操作。当然,仍然需要保护文件。
答案 7 :(得分:0)
通常的路线是使用define
:
define('MYSQL_USER', 'ROOT');
并通过MYSQL_USER
$user = MYSQL_USER;
但是这种方式不支持数组。
答案 8 :(得分:0)
几乎没有可能:
您可以使用配置文件(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-&gt; var1)
或
static class Config
{
public static $var1 = 'xxx';
public static $var2 = 'yyy';
}
(print c :: $ var1)
最好的是拥有注册表类型类,实现单例模式并能够从给定文件中读取配置。
答案 9 :(得分:0)
的Telnet?我已经陷入了时间扭曲,并于1992年到来!
但严重的是,IIRC有一些工具允许asp.net(和其他语言)解析会话数据 - 这只是一个序列化的php数组。我将实现全局设置作为PHP中的一种影子会话。即使您没有将配置设置存储为序列化PHP数组,也可以使用自己的会话处理程序在运行时将它们映射到会话中。
就存储数据的位置而言 - 当您可能在Microsoft平台上运行时,这是一个更棘手的问题。显然,您不希望每个请求都支付磁盘访问费用。虽然NT做了一些磁盘缓存但它(IME)并不像其他操作系统那样有效。 Memcached似乎是一个解决方案。它来自asp.net。{/ p>。appear to be usable
HTH
答案 10 :(得分:0)
为了可测试,我使用一个包含实际配置数据的Config
类和一个AppConfig
静态类,该类包含对从应用程序引导时加载的Config
对象的引用宽配置文件(在引导程序注入的依赖项)。在测试环境中,我只更改Config
对象。见https://github.com/xprt64/Config