在PHP项目中使用配置文件


Using configuration files in a PHP project

我需要在我的网站上有一些配置选项

我认为如果在不同的文件中放置不同的选项会更容易维护。

我还需要有一个类从不同的配置文件检索选项。

在我的网站目录结构中,我创建了一个名为/setup 的目录。

在这个目录中,我有几个文件用于不同的配置选项,例如:/setup/base.php

base.php的内容如下所示:

$setup = new stdClass();
$setup->currencies = array('USD', 'EUR', );
$setup->locations = array('local', 'international', );

我想创建一个类来读取文件并返回不同的选项。

class Options
{
    function __construct($option)
    {
        if (!is_file(SETUP_DIR.'/'.$option.'.php')) {
            thrown new Exception('Configuration file not found.');
        }
        $options = // get information from file
        return $options; // this should return the currencies and locations
    }
}
$options = new Options('base');

但是我不知道这样做是否正确。

如果是这样的话,我想不出一种从类的设置文件中检索选项的方法。

你能帮我一下,或者至少给我指个方向吗?

嗯,我不认为有一个正确的方法:Zend使用.ini文件,Codeigniter有一组数组,Symfony使用YAML。Wordpress将大部分内容存储在数据库中,并且只包含一个配置文件。

就我个人而言,我偏爱ini文件——ini是到处都在使用的东西,所以它有一种感觉,"我可以在必要时重用它",但我认为这里唯一"错误"的解决方案是不一致的——如果你在使用ini,使用ini, if数组,数组,但不要混合。

在您的情况下,有几个选项。这两种似乎是最常见的。(这两个例子都假设stdClass对象在加载的文件中被命名为$options)您可以创建一个包装器:

class Options
{
    private $_options;
    function __construct($option)
    {
        if (!is_file(SETUP_DIR.'/'.$option.'.php')) {
            thrown new Exception('Configuration file not found.');
        }
        require(SETUP_DIR.'/'.$option.'.php');
        $this->_options = $options;
        // you shouldn't put a return in a constructor 
    }
    // this will point to the internal _options variable.
    // making it a read-only access to the values from $option
    public function __get($name){ return $this->_options->$name; }
}

或者,您可以使用单例模式,只返回单个类中的对象:

class OptionsRetriever
{
    private $_fetched;
    private static $_instance;
    private __construct(){}
    public static function &getInstance()
    {
        if( !isset( self::$_instance ) ) self::$_instance = new OptionsRetriever();
        return self::$_instance;
    }
    public function getConfig( $name )
    {
        if( !isset( $this->_fetched[ $name ] ) )
        {
            require(SETUP_DIR.'/'.$name.'.php');
            $this->_fetched[ $name ] = $options;
        }
        return $this->_fetched[ $name ];
    }
}

或者,您可以将它们组合起来:

class Options
{
    private $_options;
    function __construct($options)
    {
        $this->_options = $options;
    }
    public function __get($name){ return $this->_options->$name; }
}
    // replace getConfig with this
    public function getConfig( $name )
    {
        if( !isset( $this->_fetched[ $name ] ) )
        {
            require(SETUP_DIR.'/'.$name.'.php');
            $this->_fetched[ $name ] = new Options( $options );
        }
        return $this->_fetched[ $name ];
    }

您可以使用ini文件的概念和PHP中的parse_ini_file函数来完成此操作。在php.net函数页面上有清晰的例子:parse_ini_file @ PHP。净

您可以只包含base.php文件,如下所示:

class Options
{
    function __construct($option)
    {
        if (!is_file(SETUP_DIR.'/'.$option.'.php')) {
            thrown new Exception('Configuration file not found.');
        }
        include_once(SETUP_DIR.'/'.$option.'.php');
        $options = $setup; // make sure your variable in the config is allways named $setup
        return $options; // this should return the currencies and locations
    }
}
$options = new Options('base');
echo $options->currencies[0]; //should print 'USD' provided that your base.php file from the question was used.

如果您不希望这些值直接存储在PHP中,则需要包含包含这些值的PHP文件,例如作为变量,常量或类。

我喜欢使用的一种方法是将配置存储在XML文件中,然后加载和解析该文件。如果您喜欢JSON格式,也可以使用相同的方法。只要确保你阻止了任何浏览器访问这些文件