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 :

Retrouver une variable dans une fonction de callback [PHP 7]


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2016
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2016
    Messages : 95
    Par défaut Retrouver une variable dans une fonction de callback
    Bonjour,

    J'ai une chaîne de caractères, qui contient des variables, que je dois remplacer par leur valeur.
    Quand je parle de variables, ce sont des expressions que j'ai inventé, pour permettre à des avocats de composer des courriers dynamiques.
    Exemple : Je m'appelle {avoNom}, mon prénom est {avoPrenom}, j'habite {avoAdresse}, dans la ville de {avoVille}, dont le code postal est {avoPostal}

    Les avocats composent leurs modèles, y insèrent des variables, qui afficheront leur nom, celui du client, de l'adversaire, etc ...
    Tout ceci fonctionne.

    Nom : modele01.png
Affichages : 119
Taille : 115,9 Ko

    Maintenant, je voudrais remplacer lesdites {variables} entre accolades par la valeur de la méthode.
    J'ai un objet avocat = new Avocat(id);
    avocat->getNom() rend son nom de famille
    avocat->getPrenom() rend son prénom
    etc ...

    J'ai construit un tableau associatif, qui rend la méthode à appeler, sur base de la variable, qui en est la clef.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     public static $champs = array
     (
      'avoNom' => 'lAvocat->getNom',
      'avoPrenom' => 'lAvocat->getPrenom',
      'avoTel' => 'lAvocat->getTel',
      'avoFax' => 'lAvocat->getFax',
     ...
    );
    Ensuite, je passe la chaîne à une fonction, qui extrait, par une regex, les champs, et appelle le tableau associatif.
    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
     
     public static function champsValeurs($pChaine, $lAvocat)
     {
      if(substr_count($pChaine, '{') == substr_count($pChaine, '}'))
      {
       $pChaine = preg_replace_callback
       (
        '/\{[a-zA-Z]*\}/',
        function($matches)
        {
         $clef = preg_replace('/\{|\}/', '', $matches[0]);
         $valeur = self::$champs[$clef]();
         return($valeur);
        },
        $pChaine
       );
      }
      return($pChaine);
     }
    D'abord, un petit test bidon, pour voir si j'ai autant d'accolades ouvrantes que fermantes.
    ensuite, avec preg_replace_callback
    1. j'appelle une fonction sur chaque clef entre accolades,
    2. lui enlève ses accolades, avec une autre regex
    3. et la passe au tableau associatif, qui me rend le nom de la méthode à appeler, que j'appelle dynamiquement en lui accolant deux parenthèses ()


    Et là, c'est le drame. mon paramètre $lAvocat n'est pas reconnu de la callback appelée par preg_replace_callback.
    Par contre, quand j'enlève les deux parenthèses () après le nom de la fonction, je le vois bien en sortie.
    Je m'appelle lAvocat->getNom, mon prénom est lAvocat->getPrenom, j'habite lAvocat->getAdresse, dans la ville de lAvocat->getVille, dont le code postal est lAvocat->getPostal

    Il a bien remplacé mes {variables} par les noms des méthodes à appeler. J'y suis presque :-)
    Mais comment retrouver mon objet $lAvocat dans la callback de preg_replace_callback, pour y obtenir la valeur effectivement retournée par les getters, plutôt que le nom desdits getters ?

    Voici ce que ça donne, sans les parenthèses
    Nom : modele02.png
Affichages : 115
Taille : 106,5 Ko

    Merci pour votre réponse.
    Christian.

  2. #2
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Salut,

    il est possible d'injecter des variables dans une closure comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function($matches) use ($lAvocat) {
        $lAvocat->getNom(); // ...
    };

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2016
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2016
    Messages : 95
    Par défaut La closure accède bien à la variable donnée par use
    Merci Rawsrc, tu m'as donné un bon conseil.
    J'ai ajouté un use à la callback. La variable $lAvocat y est bien accessible
    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
     
     public static function champsValeurs($pChaine, $lAvocat)
     {
      if(substr_count($pChaine, '{') == substr_count($pChaine, '}'))
      {
       //$pChaine = $lAvocat->getNom(); // OK, j'obtiens bien le nom, en mettant la suite, preg_replace_callback(...), en /* */
       $pChaine = preg_replace_callback
       (
        '/\{[a-zA-Z]*\}/',
        function($matches) use ($lAvocat)
        {
         $clef = preg_replace('/\{|\}/', '', $matches[0]);
         //$valeur = $lAvocat->getNom(); //, ça marche. $lAvocat est accessible dans la callback. La callback délivre bien son nom.
         $valeur = self::$champs[$clef](); // Call to undefined function lAvocat->getNom()
         return($valeur);
        },
        $pChaine
       );
      }
      return($pChaine);
     }
    Dans la closure, je lui demande d'affecter $lAvocat->getNom() à la valeur de retour, et je l'obtiens.
    Ton conseil est donc bon. Merci.
    Par contre, si je tente d'accéder à $lAvocat->getNom() par le tableau dont je donne la clef, j'obtiens toujours une erreur.
    Même lorsque j'essaye d'y accéder depuis la chaîne délivrée par le tableau, ça ne marche pas.
    En passant par une variable intermédiaire, dans la callback :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
         $intermedi = self::$champs[$clef];
         $valeur = $intermedi(); // Call to undefined function lAvocat->getNom()
    Si j'enlève les deux parenthèses, après $intermedi, j'obtiens bien le nom de la fonction à appeler.
    Mais lorsque je l'appelle, avec ou sans variable intermédiaire, j'obtiens une erreur.
    Ca bugue donc au niveau des parenthèses.
    Sais-tu pourquoi ?
    Merci,
    Christian.

    Nom : modele03.png
Affichages : 108
Taille : 106,1 Ko

    Ma version de PHP est
    christian@jupiter:~$ php -version
    PHP 7.0.33-0ubuntu0.16.04.4 (cli) ( NTS )
    Copyright (c) 1997-2017 The PHP Group
    Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.0.33-0ubuntu0.16.04.4, Copyright (c) 1999-2017, by Zend Technologies
    christian@jupiter:~$

  4. #4
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2016
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2016
    Messages : 95
    Par défaut Documentation sur les fonction variables
    Ils proposent des solutions sur
    https://www.php.net/manual/fr/functi...-functions.php
    Mais elles ne concernent que les méthodes d'un objet, et non tout l'objet lui-même.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $monObjet->$methodeVariable()

  5. #5
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Salut,

    je vais te donner la soluce mais je te déconseille fortement l'approche que tu as choisie
    tu dois faire :
    et veille bien à ce que $valeur se termine bien par le ; final.

    Je pense que tu devrais juste passer des noms de méthodes ou des accesseurs ou carrément et c'est mon choix préféré : n'avoir qu'un tableau clé -> valeur avec le texte qui va bien, tout le travail d'hydratation tu le fais en amont de la vue.

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2016
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2016
    Messages : 95
    Par défaut Merci Rawsrc, c'est ce que j'ai fait.
    Effectivement
    Je me suis rendu compte que j'ai visé trop gros, en faisant des fonctions et des objets dynamiques.
    Aussi, je fais le travail d'hydratation de mes variables en amont, puis, je les invoque dans ma callback, et ça marche.
    Tu avais raison.

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    <?php
     $lesChamps = array
     (
      'avoNom' => $lAvocat->getNom(),
      'avoPrenom' => $lAvocat->getPrenom(),
      'avoTel' => $lAvocat->getTel(),
      'avoFax' => $lAvocat->getFax(),
      'avoGsm' => $lAvocat->getGsm(),
      'avoEmail' => $lAvocat->getEmail(),
      'avoIbanPro' => $lAvocat->getIbanPro(),
      'avoIbanTiers' => $lAvocat->getIbanTiers(),
      'cabNom' => $leCabinet->getNom(),
      'cabAdresse' => $leCabinet->getAdresse(),
      'cabPostal' => $leCabinet->getPostal(),
      'cabVille' => $leCabinet->getVille(),
      'dossRef' => $leDoss->getNosRef(),
      'dossObjet' => $leDoss->getObjet(),
      'dossRole' => $leDoss->getRole(),
      'dossJusti' => $leDoss->getJusticiablesPr(),
      'dossBranche' => $leDoss->getBrancheFr(),
      'dossPrest' => number_format($leDoss->getSommePrest(true), 2, '.', ' ').' &euro;',
      'dossProv' => number_format($leDoss->getSommeProv(true), 2, '.', ' ').' &euro;',
      'dossTiers' => number_format($leDoss->getBalTiers(), 2, '.', ' ').' &euro;',
      'dossPoints' => number_format($leDoss->getNbPoints(), 2, '.', ' ')
     );
     
     function champsValeurs($pChaine, $pChamps)
     {
      if(substr_count($pChaine, '{') == substr_count($pChaine, '}'))
      {
       $pChaine = preg_replace_callback
       (
        '/\{[a-zA-Z]*\}/',
        function($matches) use ($pChamps)
        {
         $clef = preg_replace('/\{|\}/', '', $matches[0]);
         $valeur = $pChamps[$clef];
         return($valeur);
        },
        $pChaine
       );
      }
      return($pChaine);
     }
    ?>
    Bien à toi,
    Christian.

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

Discussions similaires

  1. [Débutant] Utiliser une fonction de Callback directement dans le code.
    Par kaker dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 28/03/2012, 13h15
  2. Problème de variable fantôme dans une fonction de callback
    Par kyfr59 dans le forum ActionScript 3
    Réponses: 6
    Dernier message: 23/03/2011, 11h35
  3. Réponses: 3
    Dernier message: 08/08/2010, 23h12
  4. Concaténer une variable dans la fonction system
    Par majudis dans le forum Débuter
    Réponses: 9
    Dernier message: 06/04/2010, 15h20
  5. Utilisation d'une même variable dans différents fonctions de Callback
    Par houjuventini dans le forum Interfaces Graphiques
    Réponses: 1
    Dernier message: 16/11/2007, 08h58

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