我有一个通用的功能集,我想嵌入到使用该应用程序的Zend_Config
实例内的configs
参数的Zend_Application
实例。但是,从属配置文件希望能够引用相对于自身的路径中的内容。例如:
美元/应用程序/配置/application.ini:
[base]
config[] = APPLICATION_PATH "../CasCommon/Configs/common.ini
/CasCommon/配置/美元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
,常量将按您想要的方式计算。
注释后编辑
我发现关于上述的争论没有足够的自动意义。在标准的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个声誉就没有意义了。
另一个选项是(如果您将allowModifications
选项设置为true)更改工作目录,然后对文件夹进行realpath。或者甚至在加载文件后加上路径。
$config = new Zend_Config_Ini('config.ini', 'section', array(
'allowModifications' => true,
));
$dir = getcwd();
chdir('..');
$config->path = realpath($config->path);
chdir($dir);