IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

preg_replace, flag e, patterne existe ou pas [RegEx]


Sujet :

Langage PHP

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2004
    Messages : 43
    Points : 22
    Points
    22
    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.

  2. #2
    Expert éminent sénior

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Points : 17 778
    Points
    17 778
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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);

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2004
    Messages : 43
    Points : 22
    Points
    22
    Par défaut
    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

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2004
    Messages : 43
    Points : 22
    Points
    22
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  5. #5
    Expert éminent sénior

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Points : 17 778
    Points
    17 778
    Par défaut
    Sans erreur de syntaxe ça fonctionnera mieux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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}');

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2004
    Messages : 43
    Points : 22
    Points
    22
    Par défaut
    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

  7. #7
    Expert éminent sénior

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Points : 17 778
    Points
    17 778
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    return (!isset($m[3])) ? ${$m[1]}[$m[2]] : ${$m[1]}[$m[2]][$m[3]];

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2004
    Messages : 43
    Points : 22
    Points
    22
    Par défaut
    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

  9. #9
    Expert éminent sénior

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Points : 17 778
    Points
    17 778
    Par défaut
    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).

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2004
    Messages : 43
    Points : 22
    Points
    22
    Par défaut
    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

  11. #11
    Expert éminent sénior

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    6 152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 6 152
    Points : 17 778
    Points
    17 778
    Par défaut
    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.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2004
    Messages : 43
    Points : 22
    Points
    22
    Par défaut
    Ben bien le merci pour ces éclaircissement :-) On arrive enfin au bout !

    Bonne continuation !

    A+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. verifier si un repertoir existe ou pas
    Par spootnic22 dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 10/11/2006, 12h58
  2. [Module de chargement] Ça existe ou pas ?
    Par brisso dans le forum Langage
    Réponses: 3
    Dernier message: 26/05/2006, 12h47
  3. Comment tester si un dossier existe ou pas?
    Par Hamdi Hedhili dans le forum C++
    Réponses: 2
    Dernier message: 06/12/2005, 09h44
  4. Réponses: 2
    Dernier message: 05/09/2005, 16h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo