简体   繁体   English

使用Zend_Config_Ini时,如何指定相对于配置文件位置的文件路径?

[英]How does one specify a file path relative to the location of the config file when Zend_Config_Ini is in use?

I've got a common set of functionality I'd like to embed into a Zend_Application instance using the configs parameter inside of that app's Zend_Config instance. 我想使用该应用程序的Zend_Config实例内部的configs参数将一组通用功能嵌入到Zend_Application实例中。 However, the slaved configuration file would like to be able to refer to things in a path relative to itself. 但是,从属配置文件希望能够引用相对于其自身的路径中的内容。 For instance: 例如:

$/application/configs/application.ini: $ /应用/ CONFIGS /的application.ini:

[base]
config[] = APPLICATION_PATH "../CasCommon/Configs/common.ini

$/CasCommon/Configs/common.ini $ / CasCommon / CONFIGS /使用common.ini

[base]
resources.frontController.controllerDirectory[] = PATH_TO_THIS_IN_DIR "../Controllers"
resources.frontController.actionHelperPaths.Cas_Common_Helper = PATH_TO_THIS_IN_DIR "../ControllerHelpers"
;...

How might one accomplish such a thing? 一个人怎么能做到这样的事情?

PHP supports constants in Ini files, but unfortunately not magic constants, so you cannot use __DIR__ , which would solve the problem. PHP支持Ini文件中的常量,但不幸的是,它不支持魔术常量,因此您不能使用__DIR__来解决问题。 The easiest and most obvious thing would be defining the path to the application.ini file as a constant just like you did with APPLICATION_PATH , eg 最简单,最明显的方法是将application.ini文件的路径定义为常量,就像使用APPLICATION_PATH ,例如

// application.ini
foo = INI_PATH '/../somewhere/else'

// index.php
const INI_PATH = '/path/to/config/folder';

Then just load your Zend_Application regularly or instantiate a new Zend_Config and the constant will be evaluated like you wanted. 然后,只需定期加载您的Zend_Application或实例化一个新的Zend_Config ,常量将按照您的需要进行评估。

Edit after comments 评论后编辑

I find that argument about the above being not automagic enough moot. 我发现关于上述观点的争论不够自然。 In a standard ZF project, the APPLICATION_PATH is defined in the index.php file and that's also where the default application.ini is loaded . 在标准ZF项目中,在index.php文件中定义了APPLICATION_PATH ,这也是默认的application.ini加载的位置 All you have to do is add the constant there. 您所要做的就是在其中添加常量。 The Ini file won't exist on it's own anyway so someone will have to call an external library at some point (likely you as the developer). Ini文件本身将不存在,因此有人必须在某个时候调用外部库(可能您是开发人员)。 The above solution requires one line of setup. 上述解决方案需要一行设置。 Any other solution requires more work. 任何其他解决方案都需要更多的工作。

If that is not good enough for you, you can extend Zend_Application to automatically add that constant before the application.ini gets loaded: 如果那对您还不够好,您可以扩展Zend_Application以在加载application.ini之前自动添加该常量:

class My_Zend_Application extends Zend_Application
{
    protected function _loadConfig($file)
    {
        if (!defined('PATH_TO_INI')) {
            define('PATH_TO_INI', dirname(realpath($file)));
        }
        return parent::_loadConfig($file);
    }
}

Of course, you will still have to change index.php to use your extended My_Zend_Application then which is why I find this approach rather pointless given that you can also just add the constant in the index.php file. 当然,您仍然必须更改index.php才能使用扩展的My_Zend_Application ,这就是为什么我觉得这种方法毫无意义,因为您还可以只在index.php文件中添加常量。

A custom Zend_Application will limit you to the application.ini of course because you cannot change the constant at runtime anymore. 当然,自定义Zend_Application将限制您使用application.ini,因为您无法再在运行时更改常量。 So if you need this functionality for multiple Ini files and not just the application.ini, extend Zend_Config_Ini and check each value for a Relative Path marker before it is returned, eg 因此,如果您需要多个Ini文件(而不仅仅是application.ini)具有此功能,请扩展Zend_Config_Ini并在返回之前检查相对路径标记的每个值,例如

class My_Config_Ini extends Zend_Config_Ini
{
    protected $_relativePath;
    protected $_relativePathMarker = '%REL_PATH%';
    public function __construct($filename, $section = null, $options = false)
    {
        $this->_relativePath = dirname(realpath($filename));
        parent::__construct($filename, $section, $options);
    }
    public function get($name, $default = null)
    {
        if (array_key_exists($name, $this->_data)) {
            return $this->_containsRelativePathMarker($this->_data[$name])
                ? $this->_expandRelativePath($this->_data[$name])
                : $this->_data[$name];
        }
        return $default;
    }
    protected function _containsRelativePathMarker($value)
    {
        return strpos($value, $this->_relativePathMarker) !== FALSE;
    }
    protected function _expandRelativePath($value)
    {
        return str_replace('%REL_PATH%', $this->_relativePath, $value);
    }
}

The above assumes you write your Ini files with something like 以上假设您使用类似以下内容编写Ini文件

foo = %REL_PATH% '/../foo.txt'

If that is still not what you are looking I can only encourage you once more to put up precise requirements. 如果那仍然不是您想要的,我只能再一次鼓励您提出确切的要求。 There is no point in offering 500 reputation when you are not going to accept any answers here because we failed to read your mind. 当您不愿意在这里接受任何答案时,提供500个信誉是没有意义的,因为我们没有读懂您的想法。

Another option would be (if you have the allowModifications option set to true) is to change the working directory, then realpath the folder. 另一个选择是(如果您将allowModifications选项设置为true)是更改工作目录,然后将文件夹更改为realpath。 Or even prepend the path on after loading the file. 甚至在加载文件后将路径放在前面。

$config = new Zend_Config_Ini('config.ini', 'section', array(
    'allowModifications' => true,
));
$dir = getcwd();
chdir('..');
$config->path = realpath($config->path);
chdir($dir);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM