【发布时间】:2011-08-20 21:27:56
【问题描述】:
为用 PHP 编写的 Web 应用程序存储配置的方法?
我见过人们使用 .ini、基本 .php 等。
另外,define() 还是简单的全局变量?
您能找到的大部分信息。
另外,数据库是存储配置的好方法吗?
【问题讨论】:
标签: php configuration global-variables ini
为用 PHP 编写的 Web 应用程序存储配置的方法?
我见过人们使用 .ini、基本 .php 等。
另外,define() 还是简单的全局变量?
您能找到的大部分信息。
另外,数据库是存储配置的好方法吗?
【问题讨论】:
标签: php configuration global-variables ini
我已经调整了 James 和 Zachu 的代码。这是我的实现。 当搜索一个值并且如果存在则返回它,否则返回一个空字符串。这样就不会显示任何通知。有一个删除方法。 cmets 和代码格式化。
<?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;
}
}
【讨论】:
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 类或任何其他子类中非常重要。
【讨论】:
实际上@Roger Ng 指出,接受的答案实际上不起作用。问题是你不能在静态方法中使用$this。
PHP: Static Keyword - 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',
));
我的 config.php 如下所示:
Config::merge(array(
'key' => 'newvalue',
'key3' => 'value3',
));
在实际代码中,我将通过编写Config::get('key') 以在接受的答案中完成的确切方式获取我的配置值。
【讨论】:
没有“最佳方式 (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 所要做的就是解释文件 - 除了将文件包含到脚本中的最小开销之外,没有网络 IO 或任何额外开销。您将存储在这些 PHP 文件中的内容包括您的 MySQL 连接凭据、Web 服务连接凭据等。
对于拥有大量用户和大量自定义设置的应用程序,您可能需要部署方法的“混合”,或者提出自己的方法。对于只是标准应用程序部署的东西,您也许可以使用非常简单的config.php 类型方法。
【讨论】:
Config::get() 时出现此错误Fatal error: Using $this when not in object context。
我认为没有最好的方法,每种方法都有其优点和缺点。只需确保配置文件(尤其是当它包含密码时)在公共目录中不可用,但在某个私有目录中。
将配置存储在数据库中可能有效,但您仍需要将数据库连接信息存储在某处以获取连接。我个人从来不是这种方法的粉丝。唯一的好处是可以轻松在线更改配置项的值,或者在用户级别进行配置。
使用define(); 将创建常量,您无法在运行时更改其中的值。在某些情况下这有效,在其他情况下则无效。如果您希望您的配置随处可用 - 在每个范围内 - 您可以考虑将配置读入一个类(可能是单例模式?),以便您可以在任何地方访问配置值。
我使用包含的 php 文件、.ini 文件、XML 文件和 JSON 文件进行配置,我个人更喜欢避免使用 .php 配置文件,因为我在我的 Web 应用程序中的不同应用程序的多种语言之间共享我的配置文件,并坚持其他“标准”。
【讨论】:
.ini 不是存储配置的好方法,因为网络服务器会将其显示给公众。不要这样做。
将配置存储在 .php 文件中。您可以使用全局变量、define() 或普通变量。定义通常是最好的选择。为了更安全,请将其放在公共目录之外。
我通常将数据库设置放在 config.php 上,并将所有动态设置放在数据库上。所有没有太大变化的设置通常都可以放在配置文件中。比如路径等。
【讨论】: