如何在Zend_Config_Ini正在使用时指定相对于配置文件位置的文件路径?
我已经使用该应用的Zend_Config
实例中的configs
参数将一组共同的功能嵌入Zend_Application
实例中。但是,从属配置文件希望能够引用相对于其自身的路径中的东西。例如:如何在Zend_Config_Ini正在使用时指定相对于配置文件位置的文件路径?
$ /应用/ CONFIGS /的application.ini:
[base]
config[] = APPLICATION_PATH "../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"
;...
一个怎么可能完成这样的事情?
PHP支持Ini文件中的常量,但不幸的是不是魔术常量,所以你不能使用__DIR__
,这将解决问题。最简单也是最明显的事情就是将application.ini文件的路径定义为一个常量,就像你对APPLICATION_PATH
所做的那样。
// application.ini
foo = INI_PATH '/../somewhere/else'
// index.php
const INI_PATH = '/path/to/config/folder';
然后,只需加载您Zend_Application
定期或实例化一个新的Zend_Config
和像你想的不断进行评估。评论后
编辑
我找到上面这样的说法没有被足够AUTOMAGIC实际意义。在一个标准的ZF项目中,APPLICATION_PATH
在index.php文件中定义,这也是default application.ini is loaded的地方。你所要做的就是在那里添加常量。 Ini文件无论如何都不会自己存在,所以有些人不得不在某个时候调用外部库(可能你是开发人员)。上述解决方案需要一行设置。任何其他解决方案都需要更多工作
如果不是对你不够好,你可以扩展到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);
}
}
当然,你仍然必须改变index.php来使用你的扩展My_Zend_Application
那么这就是为什么我觉得这个方法毫无意义,因为你也可以在index.php文件中添加常量。
自定义Zend_Application
将限制你到application.ini当然,因为你不能在运行时改变常量。因此,如果您需要针对多个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);
}
}
上述假设你写你的INI文件的东西,如
foo = %REL_PATH% '/../foo.txt'
如果这还不够,你要找我只能鼓励你一次竖起精确的要求是什么。当你不打算接受任何答案时,提供500点声望就没有意义了,因为我们没有读懂你的想法。
另一种选择是(如果您将allowModifications
选项设置为true)是更改工作目录,然后实时路径文件夹。或者甚至在加载文件之后预先加载路径。
$config = new Zend_Config_Ini('config.ini', 'section', array(
'allowModifications' => true,
));
$dir = getcwd();
chdir('..');
$config->path = realpath($config->path);
chdir($dir);
Yuck。我想它是一个解决方法。也许我会建立一个Zend_Application_Resource来执行它...:/ –
为什么Yuck?这是干净而简单的解决方案。考虑到你已经在使用'APPLICATION_PATH',为什么要用另外一个常量来创造一些额外的方法来实现这一点呢?使用明显的'PATH_TO_THIS_IN_DIR'作为另一个常量? – Gordon
因为它迫使我让客户端调用外部库来使用外部配置。整个过程就是允许某人在他们的配置中添加一行,并让所有的东西都可以使用。 –