2011-11-28 2 views
2

J'ai un ensemble commun de fonctionnalités que j'aimerais intégrer dans une instance Zend_Application en utilisant le paramètre configs dans l'instance Zend_Config de cette application. Cependant, le fichier de configuration asservi aimerait pouvoir se référer à des choses dans un chemin par rapport à lui-même. Par exemple:Comment spécifier un chemin de fichier relatif à l'emplacement du fichier de configuration lorsque Zend_Config_Ini est utilisé?

$/application/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" 
;... 

Comment peut-on accomplir une telle chose?

Répondre

3

PHP supporte les constantes dans les fichiers Ini, mais malheureusement pas les constantes magiques, donc vous ne pouvez pas utiliser __DIR__, ce qui résoudrait le problème. La chose la plus simple et la plus évidente serait de définir le chemin du fichier application.ini comme une constante, comme vous l'avez fait avec APPLICATION_PATH, par ex.

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

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

Ensuite, il suffit de charger votre Zend_Application régulièrement ou instancier une nouvelle Zend_Config et la constante sera évaluée comme vous voulez.

Modifier après les commentaires

Je trouve cet argument au sujet de ce qui précède n'étant pas automagiques assez discutable. Dans un projet ZF standard, le APPLICATION_PATH est défini dans le fichier index.php et c'est également là que se trouve le default application.ini is loaded. Tout ce que vous avez à faire est d'ajouter la constante là-bas. Le fichier Ini n'existe pas de toute façon, donc quelqu'un devra appeler une bibliothèque externe à un moment donné (probablement vous en tant que développeur). La solution ci-dessus nécessite une ligne de configuration. Toute autre solution nécessite plus de travail.

Si cela ne suffit pas bon pour vous, vous pouvez étendre Zend_Application pour ajouter automatiquement cette constante avant la application.ini se charge:

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); 
    } 
} 

Bien sûr, vous aurez encore changer index.php utilisez votre extension My_Zend_Application alors c'est pourquoi je trouve cette approche plutôt inutile étant donné que vous pouvez aussi simplement ajouter la constante dans le fichier index.php.

Un Zend_Application personnalisé vous limitera bien sûr au fichier application.ini car vous ne pouvez plus modifier la constante au moment de l'exécution. Donc, si vous avez besoin de cette fonctionnalité pour plusieurs fichiers Ini et pas seulement pour application.ini, étendez Zend_Config_Ini et vérifiez chaque valeur pour un marqueur de chemin relatif avant de le renvoyer, par ex.

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); 
    } 
} 

Le suppose que vous ci-dessus écrivez vos fichiers ini avec quelque chose comme

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

Si tel est toujours pas ce que vous cherchez, je ne peux que vous encourager une fois de plus à mettre en place des exigences précises. Il ne sert à rien d'offrir 500 points de réputation lorsque vous n'acceptez aucune réponse ici parce que nous n'avons pas lu dans vos pensées.

+0

Yuck. Je suppose que cela fonctionne comme une solution de contournement. Peut-être que je vais construire une Zend_Application_Resource qui va le faire ...:/ –

+0

Pourquoi Yuck? C'est une solution propre et simple. Étant donné que vous utilisez déjà 'APPLICATION_PATH', pourquoi inventer un moyen supplémentaire pour y parvenir en utilisant l'évident 'PATH_TO_THIS_IN_DIR' comme autre constante? – Gordon

+0

Parce qu'il me force à faire appel à une bibliothèque externe par les clients pour utiliser la configuration externe. Le but de tout cela était de permettre à quelqu'un d'ajouter une ligne à sa config et de tout faire fonctionner hors de la boîte. –

2

Une autre option serait (si vous avez l'option allowModifications définie sur true) est de changer le répertoire de travail, puis realpath le dossier.Ou même préfixer le chemin après le chargement du fichier.

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

Mais comment cela va-t-il précéder automatiquement avant que des chemins comme l'OP apparaissent dans l'exemple? – Gordon

+0

@Gordon Son aussi automatique que manuellement une constante de réglage et de le mettre dans le fichier – Petah

+0

comment? si je mets la constante, elle est automatiquement évaluée, donc un 'PATH_TO_THIS_IN_DIR" ../ Foo' sera retourné comme le '/ path/to /../foo'. Pour autant que j'ai compris votre solution, vous ajoutez seulement un chemin config variable à l'objet config. – Gordon

Questions connexes