Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 22-02-2012 22:54:28

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Nouveau View Layer pour ZF 2

Hop hop !

Quelques news pour tenir un peu au courant de ce qui se passe au niveau du développement de ZF 2. Tout d'abord, pour ceux qui sont intéressés, sachez qu'il y a maintenant des meetings toutes les semaines sur le channel IRC zf2-meeting (serveur Freenode). Les débats sont aussi bien techniques (sur l'architecture des composants) que sur l'avancement de Zend Framework 2.

Sachez tout d'abord que la bêta 3 devrait être disponible la semaine prochaine et verra l'arrivée du tout nouveau View layer, ainsi que d'une mise à jour de Zend\Db. Le travail sur la bêta 4 a déjà commencé et il concerne un gros composant : Zend\Form ! Bref, quelques trucs excitants en perspective !

Concernant le view layer, sachez qu'il a déjà été mergé au repo officiel GitHub du projet, donc vous pouvez vous amuser à le tester dès aujourd'hui ! En plus, le ZendSkeletonApp (l'application minimale d'un projet ZF 2) a déjà été mise à jour pour tenir compte de ce nouveau view layer.

J'ai commencé à l'utiliser un petit peu, donc je me permet de faire un petit retour. Si je dis de grosses bêtises (mine de rien, le nouveau View utilise énormément le système d'évènements et c'est un peu compliqué quand on veut comprendre son fonctionnement interne), n'hésitez pas à me corriger.

Le fichier de config du module gagne quelques lignes et, comme d'habitude, l'injecteur de dépendances est mis à profit (https://github.com/zendframework/ZendSk … config.php) :

Code:

/ Setup the View layer
           'Zend\View\Renderer\PhpRenderer' => array(
                'parameters' => array(
                    'resolver' => 'Zend\View\Resolver\AggregateResolver',
                ),
            ),
            'Zend\View\Resolver\AggregateResolver' => array(
                'injections' => array(
                    'Zend\View\Resolver\TemplatePathStack',
                ),
            ),
            'Zend\View\Resolver\TemplatePathStack' => array(
                'parameters' => array(
                    'paths'  => array(
                        'application' => __DIR__ . '/../view',
                    ),
                ),
            ),
            
            'Zend\Mvc\View\DefaultRenderingStrategy' => array(
                'parameters' => array(
                    'baseTemplate' => 'layout/layout',
                ),
            ),
            'Zend\Mvc\View\ExceptionStrategy' => array(
                'parameters' => array(
                    'displayExceptions' => true,
                    'template'          => 'error/index',
                ),
            ),
            'Zend\Mvc\View\RouteNotFoundStrategy' => array(
                'parameters' => array(
                    'notFoundTemplate' => 'error/404',
                ),
            ),

Le PhpRenderer est la classe qui va afficher nos vues. On peut remarquer qu'on lui injecte un resolver, appelé Zend\View\Resolver\AggregateResolver. Comme souvent avec ZF, chaque classe a un rôle bien défini, et la classe PhpRenderer ne sait que afficher les vues, mais ne sait pas comment les trouver. C'est le rôle du Resolver. L'AggregateResolver permet de cumuler plusieurs stratégie de chargement des templates, et ZF 2 en offre deux pour le moment : TemplateMapResolver et TemplatePathStack.

C'est la deuxième qu'on va utiliser le plus souvent. Le TemplatePathStack est défini juste après, et on peut voir qu'on lui injecte tout simplement comme paramètre un tableau paths, contenant les chemins vers les différents dossiers des vues.

C'est ensuite que le fun commence. On remarque trois stratégies de rendu : DefaultRenderingStrategy, ExceptionStrategy, et RouteNotFoundStrategy. Pour rester assez simple, ces stratégies vont permettre d'afficher nos vues suivant ce qui se passe en réagissant à des évènements lancés en interne par le framework (si "tout se passe bien", le "DefaultRenderingStrategy" va être utilisé, si on a une erreur 404, la "RouteNotFoundStrategy" va être utilisé à la place...). On peut remarquer également que le layout est défini directement en tant que propriété du DefaultRenderingStrategy (le composant Zend_Layout ayant complètement disparu au profit de cette solution plus flexible).

A l'utilisation, voici un exemple de contrôleur :

Code:

namespace Application\Controller;

    use Zend\Mvc\Controller\ActionController,
        Zend\View\Model\ViewModel;

    class IndexController extends ActionController
    {
        /**
         * @return \Zend\View\Model\ViewModel
         */
        public function indexAction()
        {
            return new ViewModel(array('message' => 'Une application ZF2 !');
        }
    }

Par rapport à ZF 1, on envoie donc une instance de ViewModel initialisé avec un tableau de clé -> valeurs, plutôt que de remplir directement la vue. Puis, dans la vue, on affiche comme ceci :

Code:

<?php echo $this->message; ?>

A noter que contrairement à ZF 1, les variables de la vue sont échappées automatiquement (plus besoin de faire les $this->escape de ZF 1 big_smile). Pour obtenir la valeur "brut", il faut appeler la fonction raw ($this->raw('message')).




J'ai également essayé de "comprendre" en interne comment ça fonctionnait, peut-être que ça peut en intéresser d'autres. Encore une fois, si je dis de grosses bêtises, n'hésitez pas à me corriger ;-).

Bref, si on prend le cas de la classe du DefaultRenderingStrategy, on y trouve le code suivant :

Code:

public function attach(EventCollection $events)
    {
        $this->listeners[] = $events->attach('render', array($this, 'render'), -10000);
    }

En fait, cette ligne signifie que la classe DefaultRenderingStrategy va "écouter" l'évènement render, et, si cet évènement est lancé, va appeler la fonction render de la classe (cet évènement étant lancé dans la fonction "completeRequest" de la classe Zend\Mvc\Application, une fois que la requête a été résolue).

La fonction render de cette classe est relativement légère :

Code:

public function render(MvcEvent $e)
    {
        $result = $e->getResult();
        if ($result instanceof Response) {
            return $result;
        }

        // Martial arguments
        $request   = $e->getRequest();
        $response  = $e->getResponse();
        $viewModel = $e->getViewModel();
        if (!$viewModel instanceof ViewModel) {
            return;
        }

        $view = $this->view;
        $view->setRequest($request);
        $view->setResponse($response);
        $view->render($viewModel);

        return $response;
    }

Comme on peut voir, elle récupère la requête, la réponse, le view model (ce qui a été retournée dans l'action du contrôleur), et rebalance tout ça avec l'appel $view->render($viewModel), $view étant une instance de Zend\View.

La fonction render de l'objet Zend\View est assez intéressante à comprendre, puisque c'est dedans que se passe également la fonctionnalité du layout :

Code:

public function render(Model $model)
    {
        $event   = $this->getEvent();
        $event->setModel($model);
        $events  = $this->events();
        $results = $events->trigger('renderer', $event, function($result) {
            return ($result instanceof Renderer);
        });
        $renderer = $results->last();
        if (!$renderer instanceof Renderer) {
            throw new Exception\RuntimeException(sprintf(
                '%s: no renderer selected!',
                __METHOD__
            ));
        }

        // If we have children, render them first, but only if:
        // a) the renderer does not implement TreeRendererInterface, or
        // b) it does, but canRenderTrees() returns false
        if ($model->hasChildren()
            && (!$renderer instanceof Renderer\TreeRendererInterface
                || !$renderer->canRenderTrees())
        ) {
            $this->renderChildren($model);
        }

        // Reset the model, in case it has changed, and set the renderer
        $event->setModel($model);
        $event->setRenderer($renderer);

        $rendered = $renderer->render($model);

        // If this is a child model, return the rendered content; do not
        // invoke the response strategy.
        $options = $model->getOptions();
        if (array_key_exists('has_parent', $options) && $options['has_parent']) {
            return $rendered;
        }

        $event->setResult($rendered);

        $events->trigger('response', $event);
    }

La première chose que fait cette fonction est de lancer l'évènement 'renderer' et s'arrête dès qu'un renderer inscrit a été trouvé. En l'occurrence, nous avons créé un PhpRenderer dans le fichier de config, c'est donc ce renderer qui sera récupéré.

De ce que j'ai compris, c'est là que le mécanisme de layout a lieu : avec l'appel de $this->renderChildren($model), le template de l'action courante est d'abord rendue :

Code:

protected function renderChildren(Model $model)
    {
        foreach ($model as $child) {
            if ($child->terminate()) {
                throw new Exception\DomainException('Inconsistent state; child view model is marked as terminal');
            }
            $child->setOption('has_parent', true);
            $result  = $this->render($child);
            $child->setOption('has_parent', null);
            $capture = $child->captureTo();
            if (!empty($capture)) {
                $model->setVariable($capture, $result);
            }
        }
    }

Zend ajoute automatiquement une variable dans le modèle avec comme nom $capture (qui vaut par défaut 'content') et comme valeur $result, qui est le résultat du template qui a été affichée. Puis en retournant dans la fonction render précédente, c'est le layout qui est rendu ($rendered = $renderer->getRender($model)).

Comme le contenu du template de l'action a été ajouté dans le modèle, c'est comme ça que l'on peut y accéder dans le layout :

Code:

<?php echo $this->doctype(); ?>

<html lang="fr">
    <head>
        <meta charset="utf-8">
    </head>

    <body>
        <section role="main">
            <?php echo $this->raw('content'); ?> // <========= ICI
        </section>
    </body>
</html>

Je ne sais pas si j'ai été très clair, j'avoue que je suis encore en train de comprendre le fonctionnement, mais une chose est sûre, c'est extrêmement bien foutu et flexible, je suis toujours impressionné par la qualité de l'architecture logicielle derrière ce truc... Toujours est-il qu'à l'usage, sans chercher à comprendre comment ça fonctionne, ce n'est finalement pas beaucoup plus compliqué que sur ZF1 (on retourne un ViewModel plutôt que d'assigner des variables à la vue), et le layout est bien plus flexible qu'avant.

N'hésitez pas à partager vos avis sur ce nouveau composant smile.

Hors ligne

 

#2 22-02-2012 23:26:22

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: Nouveau View Layer pour ZF 2

Super merci beaucoup maintenant il te reste plus qu'à faire un tour sur mon tuto doctrine 2 pour le compléter wink.

J'ai procédé à une migration rapidement et j'ai accès uniquement à la page d'accueil. Je n'arrive pas à afficher les vues en fonctions des actions du contrôleur. Surement à cause de la disparition des alias.

Je crois que je vais attendre la sortie de la beta 3 big_smile

Dernière modification par Orkin (23-02-2012 00:33:44)

Hors ligne

 

#3 05-03-2012 10:25:09

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: Nouveau View Layer pour ZF 2

Je me permet de remonter ce sujet puisque j'ai effectué la migration de mon application vers la béta 3. Et j'ai remarqué qu'il est toujours nécessaire d'utiliser les alias pour qu'il puisse trouver le contrôleur lié à l'url. Du coup certaines lignes peuvent être changées pour tenir compte des alias par rapport au ZendSkeletonApplication :

Code:

[lang=php]
// Setup the router and routes
            'Zend\Mvc\Router\RouteStack' => array(
                'parameters' => array(
                    'routes' => array(
                        'default' => array(
                            'type' => 'Zend\Mvc\Router\Http\Segment',
                            'options' => array(
                                'route' => '/[:controller[/:action]]',
                                'constraints' => array(
                                    'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                                ),
                                'defaults' => array(
                                    'controller' => 'index', // Application\Controller\IndexController
                                    'action' => 'index',
                                ),
                            ),
                            'may_terminate' => true,
                            'child_routes' => array(
                                'wildcard' => array(
                                    'type' => 'wildcard',
                                ),
                            ),
                        ),
                        'home' => array(
                            'type' => 'Zend\Mvc\Router\Http\Literal',
                            'options' => array(
                                'route' => '/',
                                'defaults' => array(
                                    'controller' => 'index', // Application\Controller\IndexController
                                    'action' => 'index',
                                ),
                            ),
                        ),
                    ),
                ),
            ),

Hors ligne

 

#4 05-03-2012 16:55:27

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Re: Nouveau View Layer pour ZF 2

Tu n'es pas obligé d'utiliser les alias. Tu peux spécifier directement le type complet (Application\Controller\IndexController plutôt que index). Personnellement je préfère. C'est un peu plus long à écrire mais ça permet de voir directement le type de l'objet en question plutôt que de devoir scroller tout en haut voir la correspondance de l'alias...

A noter qu'au niveau des routes, la bonne pratique sur ZF2 est de spécifier TOUTES les routes manuellement (via le tree route pour pas tuer les perfs... Par exemple tu spécifies une route mère "blog", qui a des routes filles "/create-article", "/remove-article"...

Toujours dans la même logique voulue de ZF2 de "tuer la magie" de ZF1 et d'améliorer les performances (il n'y a plus d'expression régulière à effectuer pour récupérer le nom du contrôleur et de l'action).

Hors ligne

 

#5 05-03-2012 17:25:47

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: Nouveau View Layer pour ZF 2

Tu aurais des exemples :p ? Parce que j'ai du mal à voir la finalité de la chose :s.

Hors ligne

 

#6 05-03-2012 23:26:54

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Re: Nouveau View Layer pour ZF 2

Hors ligne

 

#7 06-03-2012 10:10:50

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: Nouveau View Layer pour ZF 2

Je te remercie, il faut donc écrire chaque route comme tu le mentionnes au dessus. Ce qui me chagrine c'est toute la partie child_routes et compagnie.

En gros pour chaque type de route, http://monsite.fr/maroute/monaction

On a donc "maroute" qui correspond au nom que l'on passe (si on suit la logique classique de ZF c'est le nom du contrôleur) et "monaction" qui correspond à la méthode du contrôleur (et on peux en préciser un par défaut)

Si je reprend l'exemple de la doc (mes remarques en commentaires) peux-tu me confirmer si j'ai bien tout compris wink :

Code:

[lang=php]
$route = Part::factory(array(
    'route' => array(
        'type'    => 'literal',
        'options' => array(
            'route'    => '/', // route par défaut à la racine du site
            'defaults' => array(
                'controller' => 'ItsHomePage', // contrôleur par défaut
            ),
        )
    ),
    'may_terminate' => true, // on accepte des paramètres supplémentaires dans l'url ?
    'route_broker'  => $routeBroker,
    'child_routes'  => array( // on défini une route fille ?
        'blog' => array( // nom de la route
            'type'    => 'literal',
            'options' => array( // à la suite de là je ne comprend plus trop l'utilité ... :s
                'route'    => 'blog',
                'defaults' => array(
                    'controller' => 'ItsBlog',
                ),
            ),
            'may_terminate' => true,
            'child_routes'  => array(
                'rss' => array(
                    'type'    => 'literal',
                    'options' => array(
                        'route'    => '/rss',
                        'defaults' => array(
                            'controller' => 'ItsRssBlog',
                        ),
                    ),
                    'child_routes'  => array(
                        'sub' => array(
                            'type'    => 'literal',
                            'options' => array(
                                'route'    => '/sub',
                                'defaults' => array(
                                    'action' => 'ItsSubRss',
                                ),
                            )
                        ),
                    ),
                ),
            ),
        ),
        'forum' => array(
            'type'    => 'literal',
            'options' => array(
                'route'    => 'forum',
                'defaults' => array(
                    'controller' => 'ItsForum',
                ),
            ),
        ),
    ),
));

Hors ligne

 

#8 06-03-2012 11:48:55

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Re: Nouveau View Layer pour ZF 2

Le may_terminate signale à ZF que la route peut se terminer sur cette route (à savoir, à la route /, c'est-à-dire la racine du site).

child_routes permet de dire que tu définies des routes filles relatives à la route mère (en l'occurrence ici '/').

Les routes peuvent être imbriquées, donc une route fille peut également avoir des routes filles. Ici, on créé donc une route fille de la route mère '/' dont le nom est 'ras' et dont la route est '/rss'. Cette route possède elle même une route fille appelée 'sub' dont la route est /sub (la route complète étant donc /rss/sub).

L'avantage du TreeRoute c'est que, contrairement à ZF1 où les routes étaient parcourues suivant un ordre LIFO (Last In First Out), ce qui pouvait impliquer un certain coût en performance lorsque tu avais beaucoup de route (c'est pourquoi il fallait toujours définir les routes les plus probables en dernier dans le fichier de config), ici le TreeRoute utilise un B-Tree (http://fr.wikipedia.org/wiki/Arbre_B).

Du coup, quand il va tomber sur l'URL www.monsite.com/rss/sub, plutôt que de parcourir toutes les URL séquentiellement jusqu'à tomber sur la bonne, il va parcourir l'arbre de manière récursive en éliminant les branches de l'arbre qui ne correspondent pas.

Si on avait eu des routes définies ainsi :

/
    /rss
        /sub1
        /sub2
    /atom
        /atom1
        /atom2

Alors il n'aurait même pas exploré les feuilles de la branche /atom, mais uniquement celles de la branche /rss.

C'est donc super puissant comme mécanisme, puisque la recherche passe d'une complexité O(n) à O(log n).

Hors ligne

 

#9 06-03-2012 15:31:18

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: Nouveau View Layer pour ZF 2

Ok j'ai bien compris, même si je ne comprend pas vraiment le fait qu'il n'y ai plus besoin d'utiliser les alias (ça vire la "regex" donc peux être un gain de temps là dessus).

Par contre il me vient une autre question. Au niveau de la vue avant on utilisait :

Code:

[lang=php]
$this->url('nomdelaroute', array('controller' => 'aliascontroller', 'action' => 'actionvoulu'));

// ça veux dire que maintenant il n'y a plus besoin de préciser tout ça et on a seulement besoin de faire :
$this->url('nomdelaroutemère/routefille/action');

Ou est ce qu'il y a une autre solution ?

Hors ligne

 

#10 06-03-2012 16:39:56

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Re: Nouveau View Layer pour ZF 2

Mais les alias n'ont rien à voir. Un alias au niveau du Di c'set juste pour économiser du temps. Imagine que tu souhaites récupérer dans ton contrôleur un service tel que "Application\Service\AuthenticationService". Dans ton contrôleur, tu écrirais donc quelque chose comme ça :

Code:

public function fooAction()
{
     $locator = $this->getLocator(); // Récupération du Di
     $service = $locator->get('Application\Service\AuthenticationService');
}

Si tu as défini un alias tel que 'auth' => 'Application\Service\AuthenticationService', ça te permettra d'écrire juste :

$service = $locator->get('auth');

Rien de plus. Les alias ne servent qu'à ça.


Pour ta deuxième question, c'est encore mieux. Vu que chaque route à son nom, il te suffit d'écrire : $this->url('sub').

Pour peu que la route sub (route fille de la route '/rss') ait bien été définie, ça suffit smile.

Hors ligne

 

#11 06-03-2012 16:49:47

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: Nouveau View Layer pour ZF 2

Alors il y a surement quelque chose que je faisais mal :

Code:

[lang=php]
$this->url('default', array('controller' => 'index', 'action' => 'aide')); // avec la béta 2 ça me génère une url du type http://monsite.fr/index/aide où default est le nom de la route dans le fichier module.config.php

Donc c'est pas gênant en soit j'ai réussi à faire fonctionner sans les alias :p

J'ai essayé la méthode que tu indiques pour l'url : $this->url('aide') mais il me dit qu'il ne trouve pas la route. J'ai donc du mettre l'arbre complet $this->url('default/index/aide'); et pourtant toutes mes routes ont bien un nom uniques ...

Voici un exemple de ma configuration :

Code:

[lang=php]
'Zend\Mvc\Router\RouteStack' => array(
                'parameters' => array(
                    'routes' => array(
                        'default' => array(
                            'type' => 'literal',
                            'options' => array(
                                'route' => '/',
                                'defaults' => array(
                                    'controller' => 'Application\Controller\IndexController',
                                    'action' => 'index',
                                ),
                            ),
                            'may_terminate' => true,
                            'child_routes' => array(
                                'index' => array(
                                    'type' => 'literal',
                                    'options' => array(
                                        'route' => 'index',
                                        'defaults' => array(
                                            'controller' => 'Application\Controller\IndexController',
                                        ),
                                    ),
                                    'may_terminate' => true,
                                    'child_routes' => array(
                                        'aide' => array(
                                            'type' => 'literal',
                                            'options' => array(
                                                'route' => '/aide',
                                                'defaults' => array(
                                                    'action' => 'aide',
                                                ),
                                            ),
                                        ),

Dernière modification par Orkin (06-03-2012 16:52:25)

Hors ligne

 

#12 06-03-2012 23:07:30

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Re: Nouveau View Layer pour ZF 2

Autant pour moi, la syntaxe est $this->url->fromRoute('nom-de-la-route).

EDIT : en fait non. Cette syntaxe c'est pour le plugin de contrôleur Url, je pense que toi tu parles de l'aide de vue... En fait je pense que depuis la vue il faut effectivement mettre plus d'informations...

Hors ligne

 

#13 07-03-2012 09:29:16

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: Nouveau View Layer pour ZF 2

Oui je n'ai pas précisé que je parlais de la vue, au temps pour moi big_smile.

Du coup la syntaxe que j'utilise au niveau de la vue te semble correct ?

Code:

[lang=php]
$this->url('default/index/aide');

Edit : concernant le plugin du contrôleur $this->url()->fromRoute('aide'); je n'arrive pas à récupérer la route uniquement en donnant le nom de la route fille. (Route with name "aide" not found)

Dernière modification par Orkin (07-03-2012 09:55:16)

Hors ligne

 

#14 07-03-2012 10:23:30

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Re: Nouveau View Layer pour ZF 2

Hum... C'est possible que je me sois trompé alors et qu'il faille spécifier également le nom des routes mères... Faudra que je vérifie. smile

Hors ligne

 

#15 20-09-2012 00:41:13

Bouks
Membre
Lieu: Paris
Date d'inscription: 31-08-2012
Messages: 241

Re: Nouveau View Layer pour ZF 2

bakura a écrit:

A noter que contrairement à ZF 1, les variables de la vue sont échappées automatiquement (plus besoin de faire les $this->escape de ZF 1 :D). Pour obtenir la valeur "brut", il faut appeler la fonction raw ($this->raw('message')).

ATTENTION !!!

Ce n'est pas tout le temps vrai, et particulièrement si la variable fait partie d'un ensemble. Elle est donc 'non-déclarée' à "l’instanciation" du partial et ne passe aucun filtre.

Exemple pratique :

Je ne souhaite pas utiliser le partialLoop car on ne peut y mettre qu'un array passé comme modèle sans possibilité d'y ajouter d'autres variables 'non itérées' dans le processus.

J'ai donc un tableau rempli d'objets.

Dans ma vue d'action, j'appelle un partial 'line.phtml' et je lui passe le tableau.

Dans le partial je boucle avec un foreach pour afficher des propriétés de l'objet.

Si, imaginons, il y a une propriété comme par exemple :

Code:

$objet->name = '<script...';

Le script est éxécuté !


22914720

Hors ligne

 

#16 20-09-2012 10:00:45

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: Nouveau View Layer pour ZF 2

C'est normal le sujet a été ouvert lors de la beta 3 et nous sommes à la release 3 beta plus loin ! A l'époque de cette beta les variables étaient automatiquement échappée maintenant ce n'est plus le cas tu dois appeler l'aide de vue escapeHtml.

Comme ceci : $this->escapeHtml($objet->name);

Cela dit, en aparté utilisé directement l'attribut au lieu de passer par un getter c'est moche :p

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages