PHP 配置存储


PHP Configuration Storage

存储用PHP编写的Web应用程序的配置的方法?
我见过人们使用.ini、基本.php等。
另外,define()或简单的全局变量?
您可以找到的大多数信息。
另外,数据库是存储配置的好方法吗?

没有"最佳方法(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类型方法。

我认为没有最好的方法,每种方法都有其优点和缺点。只需确保配置文件(尤其是当它包含密码时)在公共目录中不可用,而是在私有的某个地方可用。

配置存储在数据库中可能有效,但仍需要将数据库连接信息存储在某个位置以获取连接。我个人从来都不是这种方法的粉丝。唯一的优点是可以轻松在线更改配置项的值,或者在用户级别进行配置。

使用 define(); 将创建常量,您无法在运行时更改其值。在某些情况下,这有效,在其他情况下则无效。如果您希望您的配置在任何地方都可用 - 在每个作用域中 - 您可以考虑将配置读取到一个类中(也许是单例模式?),以便您可以在任何地方访问配置值。

我使用了一个包含的 php 文件、.ini 文件、XML 文件和 JSON 文件进行配置,我个人更喜欢避免.php配置文件,因为我在我的 Web 应用程序中的不同应用程序在多种语言之间共享我的配置文件,并坚持其他"标准"。

.ini不是存储配置的好方法,因为Web服务器会向公众显示它。别这样。

将配置文件存储在.php文件中。您可以使用全局变量、define() 或普通变量。定义通常是最好的选择。为了提高安全性,请将其放在公共目录之外。

我通常将数据库设置放在配置上.php将所有动态设置放在数据库上。所有变化不大的设置通常都可以放在配置文件中。比如路径等。

正如@Roger Ng所指出的那样,接受的答案实际上不起作用。问题是您不能在静态方法中使用$this
PHP:静态关键字 - 手动

我想过通过以下方式处理这个问题:

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',
));

我的配置.php如下所示:

Config::merge(array(
    'key' => 'newvalue',
    'key3' => 'value3',
));

实际代码中,我将通过编写 Config::get('key') 来以在接受的答案中完全相同的方式获取我的配置值。

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]);
    }
}
?>

然后,我定义了一个扩展 this 的 Config 类,我可以在其中添加特定于此类的方法。

<?php
namespace MyNamespace'Core;
class Config extends Factory {
    protected static $_data = array();
}
?>

请注意,如果不希望规则protected static $_data = array();类或任何其他子类共享同一数组,请务必将它们添加到 Config 类或任何其他子类。

我已经调整了James和Zachu的代码。这是我的实现。当搜索值并且如果存在,则返回该值时,否则返回空字符串。这样就不会显示任何通知。有一个删除方法。注释和代码格式。

<?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;
    }
}