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 :

static::methode() comportement étrange


Sujet :

Langage PHP

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2009
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 30
    Points : 25
    Points
    25
    Par défaut static::methode() comportement étrange
    Bonjour,
    Cette question fait suite à la discussion acces-classe-fille-non-instanciee.
    Suite à cette discussion, j'ai mis en pratique le static::method(). Cela fonctionne globalement bien, mis à part un cas que je ne comprend pas: J'expose ici un cas de synthèse qui selon moi représente bien le cas que je rencontre:
    J'ai 3 classes: Classe1, ClasseMere et ClasseFille.
    Bien entendu, ClasseFille est une sous Classe de ClasseMere.
    Dans Classe1, une méthode methodeClasse1 appelle une methode statique de ClasseFille qui est définie dans ClasseMere : methodeClasseMere().
    Cette même méthode fait appel (ou devrait faire appel) à une méthode statique de ClasseFille grace à static::methodeClasseFille().
    Et là, c'est le drame car php m'explique que :
    Fatal error: Call to undefined method Classe1::methodeClasseFille() in blabla\ClasseMere.php on line 86
    Ci dessous du code plus concret
    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
     
    abstract class ClasseMere
    {
        abstract static function methodeClasseFille();
     
        function methodeClasseMere()
        {
            static::methodeClasseFille();
        }
    }
     
    class ClasseFille extends ClasseMere
    {
        static function methodeClasseFille()
        {
            print("hello");
        }
    }
    class Classe1
    {
        function methodeClasse1()
        {
            ClasseFille::MethodeClasseMere();
        }
    }
     
    $objet=new Classe1();
    $objet->methodeClasse1();
    Je cherche à ce que methodeClasseMere appelle ClasseFille::MethodeClasseFille() et non Classe1::MethodeClasseFille(). Lorsque je lance un get_called_class() depuis methodeClasseMere, j'obtiens aussi Classe1. Donc, je ne comprend vraiment pas ce qui se passe. J'ai essayé d'aller voir sur http://php.net/manual/fr/language.oo...c-bindings.php. Je n'y ai pas trouvé le problème que j'évoque.
    Merci d'avance pour votre aide

  2. #2
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static function methodeClasseMere()
    par contre : abstract + static, ca se fais pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Strict Standards: Static function ClasseMere::methodeClasseFille() should not be abstract

  3. #3
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Salut

    Tu fais référence à un topic, et tu n'as pas tenu compte d'une remarque qui disait que la classe Parente ne devrait pas faire appel à une classe Enfant.
    Théoriquement, la classe Parente ne devrait pas faire ce qui relève de l'Enfant, sinon la Parente devient totalement dépendante de la Fille.


    Si on suit le raisonnement du code, on évoque au départ la classe Fille, qui elle appelle une méthode de la classe Mère dont cette classe Mère qui devrait appeler une méthode de la classe Fille du départ.

    Ceci ne reviendrait il pas à évoquer une classe Fille appelant SA méthode (ClasseFille::methodeClasseFille) ?

    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
     
    abstract class ClasseMere {
        abstract function methodeClasseFille();
    }
     
    class ClasseFille extends ClasseMere {
        function methodeClasseFille() {
            print("hello");
        }
    }
     
    class Classe1 {
        function methodeClasse1() {
            $fille = new ClasseFille();
            $fille->methodeClasseFille();
        }
    }
     
     
     
    $objet=new Classe1();
    $objet->methodeClasse1();
    En quoi ceci ne conviendrait il pas dans ton cas ?

    S'il y a des traitements communs devraient faire avant ou après que la Méthode methodeClasseFille() soit appelée, peut être faudrait il créer une méthode dédiée à ça dans la classe Mère.
    Une classe Fille héritant des méthodes Parentes, on peu les appeler quand on veut (avant ou après).

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2009
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 30
    Points : 25
    Points
    25
    Par défaut
    Bonjour RunCodePhp,
    Merci de t'intéresser à ma question.
    Effectivement, cela conviendrait. C'est effectivement comme cela qu'était structuré mon code auparavant.
    Cependant, mon objectif est de factoriser le code et c'est pour cela que j'ai créé la méthode methodeClasseMere(). Celle ci contient l'ensemble du code qui est valable pour toutes les classes filles et devrait appeler ce qui est spécifique de chaque classe par la méthode methodeClasseFille().
    C'est pour cela que j'ai structuré le code de cette manière, chose que je ne parvenais pas à faire en statique auparavant et que je peux faire grâce à static::blabla() mais qui comme vous le voyez ne fonctionne pas dans le cas particulier évoqué.

  5. #5
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    Citation Envoyé par a066043 Voir le message
    C'est pour cela que j'ai structuré le code de cette manière, chose que je ne parvenais pas à faire en statique auparavant et que je peux faire grâce à static::blabla() mais qui comme vous le voyez ne fonctionne pas dans le cas particulier évoqué.
    si mais t'avais oublier de mettre un static

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2009
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 30
    Points : 25
    Points
    25
    Par défaut Réponse à stealth35
    Bonjour,
    Ok, il me semble que tu m'avais déjà fais cette remarque.
    J'ai donc essayé de rendre la méthode concernée non abstract. J'ai même supprimé le abstract de la classeMere, mais cela n'a rien changé. Il me dit toujours que la méthode n'existe pas sur Classe1
    Par ailleurs, pour ma culture, sais tu quelle est la raison qui interdit d'avoir cette méthode en abstract. J'arriverai à m'en passer s'il le faut mais ceci-dit, à partir du moment où tu appelle une méthode d'une classe fille depuis la classe mère, il parait nécessaire de s'assurer que la méthode de la classe fille existe. Or, il me semble bien que abstract soit utile pour cela.

  7. #7
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    Citation Envoyé par a066043 Voir le message
    Bonjour,
    Ok, il me semble que tu m'avais déjà fais cette remarque.
    J'ai donc essayé de rendre la méthode concernée non abstract. J'ai même supprimé le abstract de la classeMere, mais cela n'a rien changé. Il me dit toujours que la méthode n'existe pas sur Classe1
    Par ailleurs, pour ma culture, sais tu quelle est la raison qui interdit d'avoir cette méthode en abstract. J'arriverai à m'en passer s'il le faut mais ceci-dit, à partir du moment où tu appelle une méthode d'une classe fille depuis la classe mère, il parait nécessaire de s'assurer que la méthode de la classe fille existe. Or, il me semble bien que abstract soit utile pour cela.
    parce que faut pas confondre abstract et interface

    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
    interface ClasseFilleInterface
    {
        public static function methodeClasseFille();
    }
     
    abstract class ClasseMere
    {   
        public static function methodeClasseMere()
        {
            static::methodeClasseFille();
        }
    }
     
    class ClasseFille extends ClasseMere implements ClasseFilleInterface
    {
        public static function methodeClasseFille()
        {
            print("hello");
        }
    }
    class Classe1
    {
        public function methodeClasse1()
        {
            ClasseFille::MethodeClasseMere();
        }
    }
     
    $objet=new Classe1();
    $objet->methodeClasse1();

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Juillet 2009
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 30
    Points : 25
    Points
    25
    Par défaut Résolu
    Bon, alors tout d'abord merci Stealth35 de m'avoir encore permis de règler un problème.
    Je m'explique: Je n'avais pas bien lu ton message ou au moins la partie qui réglait mon problème:
    Code :

    static function methodeClasseMere()

    par contre : abstract + static, ca se fais pas
    En fait, j'ai effectivement omis de déclarer static la méthode methodeClasseMere. Cela a du troubler monsieur Php.
    Maintenant, cela fonctionne.
    Pour revenir à la question du abstract + static, je suis d'accord avec le fait que abstarct et interface ne soient pas pareil, mais j'ai bien besoin dans une classe mère qui ne soit pas une interface d'obliger ses filles à avoir certaines méthodes. Comment faire??????

  9. #9
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    mais j'ai bien besoin dans une classe mère qui ne soit pas une interface d'obliger ses filles à avoir certaines méthodes. Comment faire??????
    C'est abstract normalement.
    Mais en faisant quelques essais vite fait (je ne maitrise pas tout ça non plus), il faut juste déclarer les méthodes abstract au niveau de la classe Mere, et c'est au niveau des classes Filles où ce trouveront les traitements à faire.

    Si par contre on crée des méthodes non abstraites au niveau de la classe Mère, alors il y aura rien qui obligera au Filles d'avoir ces mêmes méthode.


    Citation Envoyé par stealth35
    par contre : abstract + static, ca se fais pas
    Là par contre je ne vois pas pourquoi ?

    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
     
    abstract class Transport {
        abstract static function roues();
    }
     
    class Voiture extends Transport {
        public static function roues() {
            echo '4 roues';
        }
    }
     
    class Velo extends Transport {
        public static function roues() {
            echo '2 roues';
        }
    }
     
     
    Voiture::roues(); // Affiche : 4 roues
    Velo::roues(); // Affiche : 2 roues
    Si je fais cet essai, ça fonctionne très bien.
    Au niveau conception, je ne vois pas non plus qu'est ce qui n'irait pas ?


    Par contre, et même pour des raisons de Factorisation, j'ai du mal à concevoir qu'une classe Fille soit obligée de passer par la classe Mère pour appeler sa propre méthode.
    Dans ton exemple, faire ceci reviendrait au même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ClasseFille::methodeClasseFille();
    La seule chose que je vois, c'est qu'il y aurait dans la classe Mère ClasseMere
    ::methodeClasseMere() des traitements autres que l'appel à static::methodeClasseFille()


    Dans tel cas peut être qu'au niveau de la classe fille il faudrait appeler la même méthode Parente :
    Exemple :
    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
     
    class Transport {
        public function roues() {
            // Traitement propre au parent
            echo 'Transport à ';
        }
    }
     
    class Voiture extends Transport {
        public function roues() {
            parrent::roues(); // On appel les traitement du parent
            echo '4 roues';
        }
    }
     
    $voiture = new Voiture();
    $voiture->roues();
    Devrait afficher : Transport à 4 roues

  10. #10
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    Citation Envoyé par RunCodePhp Voir le message
    Là par contre je ne vois pas pourquoi ?

    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
     
    abstract class Transport {
        abstract static function roues();
    }
     
    class Voiture extends Transport {
        public static function roues() {
            echo '4 roues';
        }
    }
     
    class Velo extends Transport {
        public static function roues() {
            echo '2 roues';
        }
    }
     
     
    Voiture::roues(); // Affiche : 4 roues
    Velo::roues(); // Affiche : 2 roues
    Si je fais cet essai, ça fonctionne très bien.
    Au niveau conception, je ne vois pas non plus qu'est ce qui n'irait pas ?
    Strict Standards: Static function Transport::roues() should not be abstract

  11. #11
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Citation Envoyé par stealth35
    Strict Standards: Static function Transport::roues() should not be abstract
    Ca date depuis quand ça ? (Je suis en Php5.3.0)
    Je suis en strict pourtant et je n'ai pas cette erreur


    Bon, jusqu'à lors j'ai jamais mis de méthode abstraites en statique, à part cet essai, donc tout va bien.
    C'est bon à savoir en tout cas.

  12. #12
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    Citation Envoyé par RunCodePhp Voir le message
    Ca date depuis quand ça ? (Je suis en Php5.3.0)
    Je suis en strict pourtant et je n'ai pas cette erreur
    depuis php 5.2 c'était comme ca, a la version 5.3.0 c'est revenu et c'est reparti après

  13. #13
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    tout ca c'est une histoire de visibilité, comme tu peux pas faire du abstract private

  14. #14
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Citation Envoyé par stealth35
    depuis php 5.2 c'était comme ca, a la version 5.3.0 c'est revenu et c'est reparti après


    C'est Php6 qui doivent leur faire perdre la raison


    Mais qu'est ce qu'il y a de tordu à déclarer des méthodes abstraites en statique selon toi ? (comme la Transport par exemple)
    De mon coté je ne parviens pas à voir où est le problème.

  15. #15
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    Citation Envoyé par RunCodePhp Voir le message


    C'est Php6 qui doivent leur faire perdre la raison


    Mais qu'est ce qu'il y a de tordu à déclarer des méthodes abstraites en statique selon toi ? (comme la Transport par exemple)
    De mon coté je ne parviens pas à voir où est le problème.
    parce que ca n'a de sens de déclarer une méthode abstraite statique parce que une méthode statique appartient toujours à a la classe. donc si tu la déclares comme abstraite, elle est ignoré et elle appartient plus à la classe ainsi qu'a chaque sous-classe

  16. #16
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Citation Envoyé par stealth35
    donc si tu la déclares comme abstraite, elle est ignoré et elle appartient plus à la classe ainsi qu'a chaque sous-classe
    Je vois ce que tu veux dire, mais je t'avouerais que je vais plus l'admettre qu'autre chose.
    Ce n'est pas d'une limpidité extrême tout ça
    On dit que l'Objet c'est abstrait, c'est peu de l'dire ...

    Merci pour ces explications

  17. #17
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 727
    Points
    10 727
    Par défaut
    Citation Envoyé par RunCodePhp Voir le message
    Je vois ce que tu veux dire, mais je t'avouerais que je vais plus l'admettre qu'autre chose.
    Ce n'est pas d'une limpidité extrême tout ça
    On dit que l'Objet c'est abstrait, c'est peu de l'dire ...

    Merci pour ces explications
    oui c'est spé, je sais pas pourquoi, pour moi ca parait logique, mais j'arrive pas a l'expliquer simplement, pense au abstract private c'est pareil

    y'a eu des demandes pour faire des classes statique : http://wiki.php.net/rfc/static-classes

  18. #18
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Citation Envoyé par stealth35
    pense au abstract private c'est pareil
    C'est bizarre, car là c'est nettement plus limpide.
    Vu qu'il n'est pas permis d'instancier une classe abstraite, une portée privée fera que la méthode ne pourra jamais être atteinte.


    Un des ces 4 cette histoire de statique sera mieux comprise mais pour le moment c'est encore flou.
    Disons que je comprends que déclarer une méthode statique au niveau de la classe abstraite, pourquoi pas, mais que cela n'empêcherait pas de le faire au niveau des classes Enfants.
    C'est cette restriction au niveau des classes Enfants qui me dérange.

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

Discussions similaires

  1. [Forms6i] Un IF-ELSIF au comportement étrange
    Par lafouine dans le forum Forms
    Réponses: 11
    Dernier message: 13/09/2005, 15h40
  2. Comportement étrange apres une désinstallation
    Par Sunchaser dans le forum Excel
    Réponses: 4
    Dernier message: 06/08/2005, 19h44
  3. comportement étrange d'une jointure ...
    Par amenis dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 10/02/2005, 21h27
  4. [Système][Runtime][Exec] Comportement étrange au lancement de BeSweet
    Par divxdede dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 06/06/2004, 09h54
  5. Réponses: 2
    Dernier message: 22/09/2003, 11h23

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