Ah les jolies variables de vue

Je ne sais pas pour vous, mais moi je ne trouve pas ça particulièrement élégant de toujours devoir passer par $this pour accéder à mes variables de vues.

Heureusement, dans le bestiaire des fonctions PHP, on dispose d'une fonction nommée extract qui crée des variables à partir d'un tableau. En la combinant à la méthode getVars de Zend_View qui permet d'obtenir l'ensemble des variables assignées à une vue, on peut exporter ces dernières sous la forme de variables locales.

<?php
<!-- Avec Zend_Viewpour accéder à la variable titleon doit passer par $this -->
<
h1><?php echo $this->title ?></h1>

<?php
// En utilisant extract, on peut exporter les propriétés publiques de l'objet vue sous
// la forme de variables locales
extract($this->getVars(), EXTR_SKIP);
?>
<h1><?php echo $title ?></h1>
?>

On utilise le drapeau EXTR_SKIP pour éviter d'écraser des variables existantes. Cette précaution est normalement inutile, car dans un script de vue, la seule variable disponible au début du script est la pseudo-variable $this (vous n'êtes pas assez sot pour utiliser des variables globales n'est-ce pas ?).

Bien entendu, on ne va pas se mettre à ajouter cette ligne au début de chaque script. Le Zend Framework a une architecture bien pensée et on peut modifier le comportement de Zend_View tout simplement en le dérivant :

<?php
class Wiip_View extends Zend_View
{
    
/**
     * Inclut le script de vue en mettant à disposition les propriétés
     * publiques de la vue sous la forme de variables.
     * $view->var devient $this->var ou $var dans le script.
     *
     * @param string Le script de vue à exécuter
     */
    
protected function _run()
    {
        
extract($this->getVars(), EXTR_SKIP);

        
// On ne peut pas appeler la méthode _run du parent car on changerait 
        // de portée. On doit donc copier/coller le code de Zend_View::_run
        
if ($this->_useViewStream && $this->useStreamWrapper()) {
            include 
'zend.view://' func_get_arg(0);
        } else {
            include 
func_get_arg(0);
        }
    }
}
?>

Au passage, on découvre comment Zend_View procède pour isoler les scripts de vue. C'est très simple en fait. Un script chargé avec la directive include hérite des variables définies au niveau de la ligne où se situe l'include. Dans la méthode _run, la seule variable disponible est $this (qui n'est pas exactement une variable d'ailleurs). Il suffit donc d'appeler extract avant l'include. On est par contre obligé de faire un vilain copier/coller, il faudra donc se méfier des prochaines évolutions du framework qui pourraient modifier le code de Zend_View::_run.

Il ne reste plus qu'à remplacer l'instance de Zend_View par une instance de notre composant Wiip_View. Comme expliqué dans la documentation, on le peut faire dans la méthode initView de l'initializer :

<?php
// On crée une instance de Wiip_View
$view = new Wiip_View();

// On récupère l'instance de l'aide d'action ViewRenderer
$viewRenderer Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');

// On passe l'instance de Wiip_View au ViewRenderer
$viewRenderer->setView($view);
?>

Comme l'accès aux variables est toujours possible en passant par $this, vous devriez pouvoir appliquer cette méthode à vos applications existantes sans trop de risques.

Commentaires

Bien vu! Je vais appliquer ça demain dans mes applications.

Excellent !

Merci beaucoup pour la petite astuce ! Je conseille à tout le monde de venir sur ton blog ! Il y a vraiment de la bonne ressource !

A bientôt !

Hey :-),

Attention à la double accolade lors de la déclaration de la classe Wiip_View.

Petit problème de copier-coller. C'est corrigé.

Ah, cette satanée fonction extract ! Je la déconseille fortement. Ca peut être bien pour les débutants PHP d'avoir des variables auto-créées, mais avec le recul et l'expérience, on s'aperçoit que tout un tas de variables sont créées alors même qu'on ne retrouve pas leur initialisation dans le code.

Pour moi, une autre des aberration du PHP (avec le non typage des variables et les fonctions qui peuvent retourner plusieurs types de données).

Ajouter un commentaire