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 :

[POO] pbm de syntaxe : appel à methode static de classe variable


Sujet :

Langage PHP

  1. #1
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 76
    Points : 76
    Points
    76
    Par défaut [POO] pbm de syntaxe : appel à methode static de classe variable
    Bonjour tout le monde...

    Voilà, j'ai une variable qui contient le nom de ma classe, et je cherche à appeler une méthode static sur cette classe, sans avoir à créer d'instance, et je tourne en rond sur la syntaxe à utiliser...

    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
     
    // description de ma classe
    class MaClasse {
      // constructeur :
      function MaClasse() { echo 'constructeur'; }
     
      // methode static :
      function & Factory() { return new MaClasse(); }
    }
     
    // Appel au constructeur en direct : (fonctionne très bien)
    $maClasse = & new MaClasse();
     
    // Appel à la méthode static en direct : (fonctionne très bien)
    $maClasse = & MaClasse::Factory();
     
    // Et maintenant le nom de ma classe est dans une variable :
    $className = 'MaClasse';
     
    // Appel au constructeur en passant par la vairable (fonctionne très bien)
    $maClasse = & new $className();
     
    // Appel à la méthode static en passant par la variable (pbm de syntaxe)
    $maClasse = & $className::Factory();
    Le message d'erreur est un "ParseError" habituel...
    Quelqu'un a une idée ?

  2. #2
    Expert confirmé
    Avatar de siddh
    Inscrit en
    Novembre 2005
    Messages
    3 868
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Novembre 2005
    Messages : 3 868
    Points : 5 011
    Points
    5 011
    Par défaut
    t as esayé de faire ca ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $call = $className."::Factory";
    $maClasse = & $call();
    Alunissage : Procédé technique consistant à déposer des imbéciles sur un rêve enfantin.

    Cours | FAQ | Sources Javascript
    Cours | FAQ | Sources PHP
    Mes Articles

  3. #3
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 76
    Points : 76
    Points
    76
    Par défaut
    Bonne idée...

    Je viens d'essayer ca me donne :
    Call to undefined function

    Il n'a pas l'air de comprendre qu'il s'agit d'une methode static d'une classe et non d'une fonction...


    Sinon il y a toujours la solution d'utiliser eval mais c'est très sale et niveau performence c'est pas le top...

  4. #4
    Expert confirmé
    Avatar de siddh
    Inscrit en
    Novembre 2005
    Messages
    3 868
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Novembre 2005
    Messages : 3 868
    Points : 5 011
    Points
    5 011
    Par défaut
    oui, apparement tu es en php4, sinon tu pourrais utiliser l api de reflection,
    Alunissage : Procédé technique consistant à déposer des imbéciles sur un rêve enfantin.

    Cours | FAQ | Sources Javascript
    Cours | FAQ | Sources PHP
    Mes Articles

  5. #5
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    hop :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?php
     
    class Toto {
        function statique() {
            echo 'Statique !';
        }
    }
     
    $class = 'Toto';
    call_user_func(array(&$class, 'statique'));
     
    ?>


    EDIT pas besoin de & apparemment :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    call_user_func(array($class, 'statique'));

  6. #6
    Expert confirmé
    Avatar de siddh
    Inscrit en
    Novembre 2005
    Messages
    3 868
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Novembre 2005
    Messages : 3 868
    Points : 5 011
    Points
    5 011
    Par défaut
    honte a moi j ai oublié ca

    pour Mr N.
    Alunissage : Procédé technique consistant à déposer des imbéciles sur un rêve enfantin.

    Cours | FAQ | Sources Javascript
    Cours | FAQ | Sources PHP
    Mes Articles

  7. #7
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 76
    Points : 76
    Points
    76
    Par défaut
    Oui, PHP4 exclusivement...

    Bon, la seule solution que j'ai trouvé est celle-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $maClasse = eval("return $className::Factory();");
    Ce qui me pose problème la-dessus, c'est que ma fonction static va traiter un objet assez volumineux et que je perd l'avantage du passage de référence en passant par la fonction eval

  8. #8
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 76
    Points : 76
    Points
    76
    Par défaut
    Merci Mr N. ca semble répondre à mon besoin!!

    Petite question, qu'en est-il de la valeur de retour ? référence ? ou copie de la valeur ?

  9. #9
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    regarde ce que je t'ai proposé. et si tu veux passer par référence :
    call_user_func_array ! (plein d'info sur la doc )

    EDIT la valeur de retour j'en sait rien ! à tester

  10. #10
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 76
    Points : 76
    Points
    76
    Par défaut
    Vu sur le site de php.net

    call_user_func ne retourne pas de référence... :-(

    seule solution passer par eval de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    eval('$maClasse = & ' . $className . '::Factory();');
    Merci pour votre aide ;-)

  11. #11
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    je confirme par le test suivant :
    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
    <pre><?php
     
     
    class Toto {
        var $attr;
        function &statique() {
            return $GLOBALS['obj'];
        }
    }
     
    $o1 =& new Toto();
    $o1->attr = 'o1';
    var_dump($o1->attr);
     
    $GLOBALS['obj'] =& $o1;
    $GLOBALS['obj']->attr = 'obj';
    var_dump($o1->attr);
     
    $class = 'Toto';
    $o2 =& call_user_func(array($class, 'statique'));
    $o2->attr = 'Passage par reference !';
    var_dump($o1->attr);
    var_dump($GLOBALS['obj']->attr);
    var_dump($o2->attr);
     
    ?>
    donne ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    string(2) "o1"
    string(3) "obj"
    string(3) "obj"
    string(3) "obj"
    string(23) "Passage par reference !"
    par contre, solution de contournement, retourner l'objet par références via les attributs ?

  12. #12
    Expert confirmé
    Avatar de siddh
    Inscrit en
    Novembre 2005
    Messages
    3 868
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Novembre 2005
    Messages : 3 868
    Points : 5 011
    Points
    5 011
    Par défaut
    ouais j'ai aussi une solution,
    tu passes a php 5 et deja t auras le mot clé statique et l'api de reflection


    ok je
    Alunissage : Procédé technique consistant à déposer des imbéciles sur un rêve enfantin.

    Cours | FAQ | Sources Javascript
    Cours | FAQ | Sources PHP
    Mes Articles

  13. #13
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 76
    Points : 76
    Points
    76
    Par défaut
    Merci...

    j'ai pour règle de ne pas modifier ma classe pour s'adapter à une utilisation spécifique... et en plus, dans mon cas, ma classe ne retourne pas vraiment d'instance, mais un tableau d'instances de plusieurs classes différentes (qui hérite de celle-ci), donc pas d'attribut...

    La solution de l'eval reste finalement la seul qui convienne à mon besoin...

    Sinon, pour la culture générale, j'ai trouvé ca sur le site de php.net :
    if you need to get a reference back from a method, you can work around call_user_func()'s shortcomings like this:

    <?

    $globalObj;

    class tClass
    {
    function &instance()
    {
    global $globalObj;
    if(!is_object($globalObj))
    {
    $globalObj = new tClass();
    }
    return $globalObj;
    }
    }

    $classname = "tClass";
    # calling the function this way won't
    # return a reference.
    $test = &call_user_func(array($classname,"instance"));
    # but if we call it again with the instance
    # that we just got, it'll be the right
    # one
    $test = &$test->instance();
    # so test is now a reference to $globalObj, just like it should be

    # let's verify it:
    $test->blah=1;

    echo "<pre>";
    print_r($test)."\n";
    print_r($globalObj);
    echo "</pre>";
    # there, now it behaves just like you'd expect

    ?>

  14. #14
    Membre régulier
    Inscrit en
    Octobre 2005
    Messages
    76
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 76
    Points : 76
    Points
    76
    Par défaut
    Citation Envoyé par siddh
    ouais j'ai aussi une solution,
    tu passes a php 5 et deja t auras le mot clé statique et l'api de reflection


    ok je
    Si ca ne tenait qu'à moi ;-) hélas, 20 personnes développent diverses applications sur le même serveur.... :-(

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 17/06/2014, 16h26
  2. Réponses: 2
    Dernier message: 14/10/2009, 09h31
  3. Réponses: 14
    Dernier message: 10/09/2009, 19h08
  4. Main : appelle de methode ou de classe ?
    Par sayag dans le forum C#
    Réponses: 15
    Dernier message: 16/06/2007, 17h32
  5. Réponses: 11
    Dernier message: 16/10/2005, 20h21

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