2011-11-28 66 views
2

我已經使用該應用的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" 
;... 

一個怎麼可能完成這樣的事情?

回答

3

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點聲望就沒有意義了,因爲我們沒有讀懂你的想法。

+0

Yuck。我想它是一個解決方法。也許我會建立一個Zend_Application_Resource來執行它...:/ –

+0

爲什麼Yuck?這是乾淨而簡單的解決方案。考慮到你已經在使用'APPLICATION_PATH',爲什麼要用另外一個常量來創造一些額外的方法來實現這一點呢?使用明顯的'PATH_TO_THIS_IN_DIR'作爲另一個常量? – Gordon

+0

因爲它迫使我讓客戶端調用外部庫來使用外部配置。整個過程就是允許某人在他們的配置中添加一行,並讓所有的東西都可以使用。 –

2

另一種選擇是(如果您將allowModifications選項設置爲true)是更改工作目錄,然後實時路徑文件夾。或者甚至在加載文件之後預先加載路徑。

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

但是在這個例子中的OP等任何路徑顯示之前,這會如何自動預先加載? – Gordon

+0

@Gordon它像自動手動設置常量並將其放入文件 – Petah

+0

怎麼樣?如果我設置常量,它會自動評估,所以'PATH_TO_THIS_IN_DIR「../ Foo將作爲'/ path/to /../ foo'返回。就我理解你的解決方案而言,你只是添加一條路徑配置變量配置對象。 – Gordon

相關問題