2009-04-15 8 views
4

Situation actuelle:PHP: "Global" Inclure

  • J'ai la version actuelle de mon framework MVC qui utilise des classes en tant que contrôleurs.
  • J'ai quelques modules "vintage" de mon ancien MVC Framework qui utilise des contrôleurs simples et plats.

très simplifié qui signifie:

Nouvelle version:

<?PHP 
class blaController extends baseController { 
    private $intVar; 

    function dosomethingFunction() { 
     $this->intVar = 123; 
     $this->view('myView'); 
    } 
} 
?> 

ancienne version:

<?PHP 
$globalVar = 123; 
// view "controllername" is automatically shown 
?> 

J'essaie maintenant d'écrire un wrapper pour être capable d'utiliser mes anciens contrôleurs dans mon nouveau MVC sans avoir à re écris tout. Pour ce faire, j'ai un contrôleur « wrapper »:

class wrapController extends baseController { 
    function dosomethingFunction() { 
     require 'old_dosomething.function.php'; 
     $this->view('old_dosomething_view'); 
    } 
} 

(Encore une fois: Ceci est très, très simplifié - juste pour l'idée sur pas le code réel..)

Le problème avec cette l'approche est, que la variable global global $ globalVar n'existe plus qu'à l'intérieur de la méthode "dosomethingFunction" et n'est pas accessible par la vue.

Ce ne serait pas le cas si je pouvais forcer le require à se comporter comme "dans la portée globale" de sorte que $ globalVar serait de nouveau disponible dans la portée globale. Donc: Y at-il un moyen d'atteindre "require_global" ou quelque chose de similaire?

(Une solution pour mon problème serait de modifier mes anciens contrôleurs pour commencer avec un tas de commandes "globales", mais je préférerais une solution où je n'ai pas besoin de changer autant de ce vieux code. (Note: S'il vous plaît ne me dites pas que les GLOBALS sont mauvais.Il manque complètement le point de cette question.Je viens d'accepter qu'il est nécessaire de garder un ancien code de travail dans un environnement plus récent et plus propre.)

Répondre

5

Vous pouvez ajouter des variables locales définies dans dosomethingFunction() à portée globale:

class wrapController extends baseController { 
    function dosomethingFunction() { 
     require 'old_dosomething.function.php'; 
     //begin added code 
     $vararr = get_defined_vars(); 
     foreach($vararr as $varName => $varValue) 
       $GLOBALS[$varName] = $varValue;    
     //end added code   
     $this->view('old_dosomething_view'); 
    } 
} 

Notez que pour que cela fonctionne comme prévu, vous devez appeler besoin avant d'utiliser toute autre chose dans la fonction. get_defined_vars() renvoie uniquement les variables de la portée actuelle, donc aucun hacks array_diff n'est nécessaire.

+0

Je ne sais pas encore pourquoi, mais de toute façon array_merge ne fonctionne pas dans mon scénario en fusionnant le tableau "manuellement" avec foreach fonctionne. – BlaM

+0

bien, $ GLOBAL n'est pas vraiment un tableau "normal". Revenir à la version foreach – vartec

1

Hmmm, c'est un problème que je n'ai jamais vu auparavant. Je suppose que vous pouvez le faire

class wrapController extends baseController { 
    function dosomethingFunction() { 
     require 'old_dosomething.function.php'; 

     // Force "old" globals into global scope 
     $GLOBALS['globalVar'] = $globalVar; 

     $this->view('old_dosomething_view'); 
    } 
} 

Mais c'est un peu fastidieux processus manuel et, selon le nombre de GLOBALS dont nous parlons. Je vais y réfléchir, mais je ne connais pas de solution de «magie automatique» au sommet de ma tête.

+0

"$ GLOBALS ['globalVar'] = $ globalVar;" serait une option si je pouvais parcourir toutes les variables locales, mais y a-t-il un moyen "automatisé" de trouver toutes ces variables? – BlaM

4

C'est la solution la plus simple à laquelle je peux penser.

Utilisez deux fois la fonction get_defined_vars() et obtenez une variable de chaque appel pour déterminer quelles variables ont été introduites par le fichier requis.

Exemple:

$__defined_vars  = get_defined_vars(); 
require('old_dosomething.function.php'); 
$__newly_defined_vars = array_diff_assoc($__defined_vars, get_defined_vars()); 
$GLOBALS = array_merge($GLOBALS, $__newly_defined_vars); 
$this->view('old_dosomething_view'); 
+0

pas besoin de faire array_diff si vous appelez cela depuis une fonction. get_defined_vars() renvoie uniquement des variables dans la portée actuelle. – vartec

+0

Bon point. Bien qu'il soit certainement possible que quelqu'un ajoute plus tard des variables à cette fonction. – Matt

+0

array_diff_assoc échoue si l'une des variables est un objet qui ne peut pas être converti en chaîne. – BlaM

0

Avez-vous essayé Zend_Registry de Zend Framework?

Le registre est un conteneur pour stocker des objets et des valeurs dans l'espace d'application. En stockant la valeur dans le registre, le même objet est toujours disponible dans votre application. Ce mécanisme est une alternative à l'utilisation du stockage global.

http://framework.zend.com/manual/en/zend.registry.html

+0

Cela nécessiterait de modifier l'ancien code qui est juste ce que j'essaie d'éviter. – BlaM

+0

... et je ne vois pas comment Zend_Registry est meilleur qu'un simple tableau global pour stocker des choses ... – BlaM

1

Pour toute personne intéressée: Mon (jusqu'à présent) version finale:

class wrapController extends baseController { 
    function dosomethingFunction() { 
     // ... do some initialisation stuff ... 

     $__defined_vars = array_keys(get_defined_vars()); 

     require 'old_dosomething.function.php'; 

     $__newly_defined_vars = array_diff(
            array_keys(get_defined_vars()), 
            $__defined_vars, 
            array('__defined_vars') 
           ); 
     foreach ($__newly_defined_vars as $var) { 
      $GLOBALS[$var] = &$$var; 
     } 

     $this->view('old_dosomething_view'); 
    } 
} 

laid, mais cela fonctionne. Merci pour votre aide!