simplexml et array_walk_recursive

Eléphanteau du PHP | 19 Messages

09 mai 2007, 19:51

Bonjour,
je suis en train de modifier le systeme de template employé sur mon site pour le rendre plus flexible. Apres une petite recherche, j'ai décidé de préférer un systeme basé sur simplexml plutot que d'utiliser des transformation xsl que je juge trop gourmande en ressource sans systeme de cache ou qu'un systeme de template plus classique type smarty, pas assez flexible pour ce que je veux faire.

La méthode commence donc par parser un fichier xml pour le convertir en object simplexml. Ensuite un série de modification sont opérées à l'objet ainsi créer (création, modification ou suppréssions de noeux...). puis le rendu est obtenu via la méthode asXML() de simplexml.

Je trouve le résultat plutot probant mais je rencontre néanmois un probleme pour remplir le dernier point du cahier des charges : L'objectif est d'appliquer une méthode à tous les derniers elements de l'object simplexml. Je pense qu'un exemple sera plus clair :

Code : Tout sélectionner

[b]Le fichier parsé : [/b] <html> <head> <title>about:blank</title> </head> <body> <div id="tete"> <form id="recherche" name="recherche" action="." method="post"> <input type="text" name="q"/> <input type="submit"/> </form> </div> <div id="contenu"> <h1>about:blank</h1> </div> [b]La méthode : [/b] <?php function __construct() { $this->xml = $this->format(simplexml_load_file($this->tpldir.$this->tpl.$this->tplext)); $this->xml->head->title .= ' | Le syndrome de la page blanche'; array_walk_recursive($this->xml,array($this,'format')); $this->xml = $this->xml->asXML(); } function format($t,$v) {$this->xml->$t = htmlentities($v);} ?>
Ici la méthode format() est censée remplacer tous les derniers éléments de l'objet xml par leur equivalent en entitées html. Malheureusement, array_walk_recursive appel correctement la méthode mais ne lui permet pas de modifier le dit élément puisque $t fait referece à l'objet de maniere relative et non absolue. Je continue de rechercher un equivalent de array_walk_recursive me permettant cela. J'ai aussi pensé à convertir l'object simplexml en array mais je perd alors l'interet de asXML().

Si vous avez des idées pour résoudre ce probleme...
Merci ^^

Eléphanteau du PHP | 19 Messages

10 mai 2007, 18:09

Je soupçonne la solution de se cacher dans l'utilisation des références au variables (&$var) car je ne parviens pas a trouver une fonction de callback adéquat. Mais évidemment je n'arrive pas à mettre cette idée en place :

Code : Tout sélectionner

function __construct() { $this->xml = simplexml_load_file($this->tpldir.$this->tpl.$this->tplext); $this->xml = $this->walk($this->xml); $this->xml = $this->xml->asXML(); } function walk(&$xml) { foreach ($xml->children() as $t=>$v) if (is_array($v) || is_object($v)) $this->walk($v); else $this->format($v); } function format(&$v) { $v = htmlentities($v); }
L'extrait ci-dessus me renvoit un message d'erreur fatale : Call to a member function asXML() on a non-object in /var/www/test.php on line 12. La ligne 12 est bien celle d'appel de asXML dans la méthode de construction de la classe. Je trouve ce message relativement encourageant puisque que je suis apparemment parvenu à altérer l'object simpleXML. Mais je ne vois pas mon erreur et j'avoue ne pas trouver d'autres solutions.

Si vous avez des idées et/ou des remarques, elles sont bienvenues.
Merci.

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

10 mai 2007, 19:25

Je n'ai pas trop suivi ce que tu cherchais à faire, mais à quoi te sert htmlentities() exactement ? asXML() sort du XML, donc les entités XML devraient être échappées et pour peu que tu ne te plantes pas dans l'en-tête Content-Type de la page tu n'as pas besoin d'échapper les entités HTML. J'ai oublié quelque chose ?

Eléphanteau du PHP | 19 Messages

10 mai 2007, 21:53

oui,
j'aurais dut préciser que la méthode format() devait réaliser plusieurs modifications sur les chaines de caracteres et cela en fonction de plusieurs elements telle que la balise, la langue etc...

htmlentities() n'est qu'un des aspect de cette fonction. Le probleme porte vraiment sur la maniere d'appeler cette fonction et non pas sur sa procedure. Désolé de ne pas avoir été plus précis.