【问题标题】:PHP Configuration StoragePHP 配置存储
【发布时间】:2011-08-20 21:27:56
【问题描述】:

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

【问题讨论】:

标签: php configuration global-variables ini


【解决方案1】:

我已经调整了 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;
    }
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      这就是我的工作。

      首先,我定义了一个通用的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 类或任何其他子类中非常重要。

      【讨论】:

        【解决方案4】:

        实际上@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') 以在接受的答案中完成的确切方式获取我的配置值。

        【讨论】:

          【解决方案5】:

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

          【讨论】:

          • +1,虽然您的示例类实际上不是单例类也不是静态类,但它仍然是最好的答案(到目前为止),甚至比我自己的更好;-)
          • 我添加了静态关键字。我的错。哈哈。
          • 我认为配置类是矫枉过正...而且您的调度程序可能使用与您的模板不同的配置。您是否为此扩展了配置类?或者制作2个物体?还是全部放在 1 中?在整个应用程序中使用一次的类 = overkill imo。
          • @Rudie,所有有效的问题都是肯定的。为整个应用程序使用单个类可能“矫枉过正”,但它会为整个应用程序生成单一的事实来源。硬币的两面肯定有原因和用例。扩展 config 类当然也是一个不错的选择,因为它将特定的配置选项集保持在一起,并允许您在每个模块的基础上通过您的配置扩展和收缩“神奇”功能。
          • 调用Config::get() 时出现此错误Fatal error: Using $this when not in object context
          【解决方案6】:

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

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

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

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

          【讨论】:

          • +1 用于公共文件夹外建议和存储与语言无关的配置
          【解决方案7】:

          .ini 不是存储配置的好方法,因为网络服务器会将其显示给公众。不要这样做。

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

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

          【讨论】:

          • 如果 .ini 位于文档根目录之外或目录受到保护,则不会。一个(可能)有效的原因是速度是关键任务,因为 .ini 需要手动解析,但 php 文件是从 php 引擎解析的,所以使用 .php 会更快。
          猜你喜欢
          • 1970-01-01
          • 2013-09-04
          • 1970-01-01
          • 2019-05-07
          • 1970-01-01
          • 1970-01-01
          • 2016-02-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多