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
常量,就会像您想要的那样评估常量。
评论后编辑
我发现关于上述内容的论点不够自动化。在标准的 ZF 项目中,APPLICATION_PATH
在 index.php 文件中定义了它,这也是默认 application.ini 的加载位置。您所要做的就是在此处添加常量。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 声望是没有意义的,因为我们没有读懂您的想法。