Précédent   Forum des professionnels en informatique > PHP > Langage > Regex
Regex Forum d'entraide sur les expressions rationnelles PHP. Avant de poster -> FAQ regex, Cours de regex et Sources de regex
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 25/10/2007, 00h05   #1
Invité régulier
 
Inscription : septembre 2004
Messages : 43
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 43
Points : 6
Points : 6
Par défaut preg_replace, flag e, patterne existe ou pas

Bonjour,

J'utilise un mini système de méta-code pour un templating.

Voici un exemple de méta-code : {site:color:bg} ou encore {page:title}

Pour remplacer tout cela par ce que je souhaite j'ai un petit regex qui utilise preg_replace avec le flag e afin de remplacer tout cela par la valeur d'une variable créée plus haut.

Exemple {site:title} => $site['title']

Donc un preg_replace('/.../e', '$$1[$2]', $template); fonctionne très bien quand j'ai un méta-code du style : {site:title}. Le problème se pose justement quand le dernier groupe ($3) n'existe pas, puisqu'il est facultatif.

Le but recherché c'est de faire : si le groupe $3 ({site:color:bg}) existe il me cherche la variable $$1[$2][$3] mais s'il y a uniquement deux groupes ({site:title}) il me fait ceci : $$1[$2].

J'ai pensé en faisant un ($3) ? $$1[$2][$3] : $$1[$2] mais ça fonctionne pas, puisque si le groupe $3 n'existe tout simplement pas, la variable n'existe pas...

Si quelqu'un à déjà eu le problème et qu'il a la solution je suis preneur :-D

Merci d'avance,

Bonne soirée.
Hacken est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/10/2007, 11h30   #2
En attente de confirmation mail
 
Inscription : juin 2002
Messages : 6 164
Détails du profil
Informations forums :
Inscription : juin 2002
Messages : 6 164
Points : 6 404
Points : 6 404
Cela sera certainement plus facile à gérer avec une fonction de callback (preg_replace_callback). Vous pourrez ainsi faire tout le nécessaire dont le test (isset) de votre troisième parenthèse capturante.
Code :
1
2
3
4
5
6
7
8
9
function my_callback($m) {
    if (isset($m[3])) {
        return $GLOBALS[$m[1]][$m[2]][$m[3]]; // A tester avant éventuellement
    } else {
        return $GLOBALS[$m[1]][$m[2]]; // A tester avant éventuellement
    }
}
 
$out = preg_replace_callback('~....~', 'my_callback', $in);
julp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/10/2007, 19h00   #3
Invité régulier
 
Inscription : septembre 2004
Messages : 43
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 43
Points : 6
Points : 6
Hello Julp,

Crétin que je suis, j'avais pas vu cette fonction dans la doc (faut dire que je suis pas allé tout en bas -___-').

J'ai en effet utilisé preg_replace_callback avec create_function parce que je suis dans une class et vraisensablement le $this-> veut pas passer :-)

Du coup ça fonctionne Pico bello !


Merci encore,

Salutations
Hacken est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/10/2007, 22h28   #4
Invité régulier
 
Inscription : septembre 2004
Messages : 43
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 43
Points : 6
Points : 6
Hello,

Je me permet de revenir car j'ai un toujours un souci avec ça. Maisje pense que ça vient plus de ma fonction callback.

Elle se présente comme ceci :
Code :
create_function('$m', 'return (!isset($[3])) ? ${$m[1]}[$m[2]] : ${$m[1]}[$m[2]][$m[3]];')
Je pense que le problème doit venir du ${$m[1]} car ça pas l'air de fonctionner.

Au départ j'avais pensé que c'était parce que la variable n'était pas globale, j'ai donc ajouté un global ${$m[1]}; avant le return mais ça fonctionne pas.. Le pire c'est que j'ai aucune erreur (error_display(E_ALL)).

J'ai également essayé avec le $GLOBALS, mais toujours aucune valeur de retour, qui j'en suis sûr il y en a, car si je fais un print_r de $site (par exemple) j'ai bien le contenu de ma variable.

Est-ce que tu penses que c'est à cause du fait que mon regex soit dans une class ?

Merci encore d'avance

Salutations
Hacken est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/10/2007, 23h26   #5
En attente de confirmation mail
 
Inscription : juin 2002
Messages : 6 164
Détails du profil
Informations forums :
Inscription : juin 2002
Messages : 6 164
Points : 6 404
Points : 6 404
Sans erreur de syntaxe ça fonctionnera mieux
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
class Test {
    private function callback($m)
    {
        if (isset($m[3])) {
            return $GLOBALS[$m[1]][$m[2]][$m[3]];
        } else {
            return $GLOBALS[$m[1]][$m[2]];
        }
    }
 
    public function parse($string)
    {
        return preg_replace_callback('~\{(.+):(.+)(?::(.+))?\}~U', array($this, 'callback'), $string);
        #return preg_replace_callback('~\{(.+):(.+)(?::(.+))?\}~U', create_function('$m', 'return (!isset($m[3])) ? $GLOBALS[$m[1]][$m[2]] : $GLOBALS[$m[1]][$m[2]][$m[3]];'), $string);
    }
}
 
$site = array(
    'a' => 1,
    'b' => array(
        'c' => 2
    )
);
 
$t = new Test;
echo $t->parse('{site:a} {site:b:c}');
julp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/10/2007, 08h41   #6
Invité régulier
 
Inscription : septembre 2004
Messages : 43
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 43
Points : 6
Points : 6
Hop,

J'ai fais une erreur de syntaxe ? Si oui tu peux me dire ou, parce que perso je ne vois vraiment pas :-/

Merci d'avance
Hacken est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/10/2007, 11h27   #7
En attente de confirmation mail
 
Inscription : juin 2002
Messages : 6 164
Détails du profil
Informations forums :
Inscription : juin 2002
Messages : 6 164
Points : 6 404
Points : 6 404
Tout d'abord c'est $GLOBALS qu'il faut utiliser (et que je ne corrige pas ci-dessous puisque je l'ai déjà fait plus haut - d'ailleurs on le voit très bien si on développe avec error_reporting avec au moins une valeur de E_ALL). Votre autre erreur est là :
Code :
return (!isset($m[3])) ? ${$m[1]}[$m[2]] : ${$m[1]}[$m[2]][$m[3]];
julp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/10/2007, 11h40   #8
Invité régulier
 
Inscription : septembre 2004
Messages : 43
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 43
Points : 6
Points : 6
J'ai collé la mauvaise ligne de code :/ du coup c'est sûr ça fonctionne moins bien.


Sinon, je suis un peu septique quand à l'utilisation du $GLOBALS, c'est pas très sécuritaire non ?

Merci d'avance
Hacken est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/10/2007, 11h55   #9
En attente de confirmation mail
 
Inscription : juin 2002
Messages : 6 164
Détails du profil
Informations forums :
Inscription : juin 2002
Messages : 6 164
Points : 6 404
Points : 6 404
Citation:
Envoyé par Hacken
Sinon, je suis un peu septique quand à l'utilisation du $GLOBALS, c'est pas très sécuritaire non ?
Le problème qui pourrait se poser est que quelqu'un détourne cette fonctionnalité pour tenter d'afficher le contenu d'une de vos variables. Cela requiert toutefois qu'elles soient connues (ou déterminables) et que vous fassiez cette interprétation sur des données que l'utilisateur vous aurait directement fournies (formulaire par exemple) ou bien que celui qui crée ou modifie un template existant ne respecte pas son "contrat" ... Vous pourriez éventuellement ajouter un contrôle type blacklist ou whitelist pour limiter les dégâts à moins de mettre en place une portée limitée (un objet de type Registre par exemple mais il faudrait revoir votre conception actuelle).
julp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/10/2007, 19h40   #10
Invité régulier
 
Inscription : septembre 2004
Messages : 43
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 43
Points : 6
Points : 6
Hello,

Désolé pour le retard de ma réponse. J'ai tout de même réussi à le faire sans utiliser le $GLOBALS :-)

Je viens de me rendre compte, que si j'avais lu les commentaires de la fonction preg_replace_callback j'aurais pu trouver la solution (puisque quelqu'un à eu le même problème et donner un bout de solution).

Néanmoins, il y a un aspect que je comprend pas très très bien, c'est le array avec $this et callback, il va faire quoi avec les deux valeurs ?


Merci d'avance
Hacken est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/10/2007, 21h30   #11
En attente de confirmation mail
 
Inscription : juin 2002
Messages : 6 164
Détails du profil
Informations forums :
Inscription : juin 2002
Messages : 6 164
Points : 6 404
Points : 6 404
La notation tableau dont le premier élément est un objet ou le nom d'une classe et dont le deuxième élément est le nom de la méthode permet respectivement de faire appel à une méthode et à une méthode statique. Sans cela vous seriez limiter à appeler de simples fonctions.
julp est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/10/2007, 21h37   #12
Invité régulier
 
Inscription : septembre 2004
Messages : 43
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 43
Points : 6
Points : 6
Ben bien le merci pour ces éclaircissement :-) On arrive enfin au bout !

Bonne continuation !

A+
Hacken est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 10h21.


 
 
 
 
Partenaires

Hébergement Web