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 :

__get() ou getXX() ?


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Inscrit en
    Février 2005
    Messages
    419
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Février 2005
    Messages : 419
    Par défaut __get() ou getXX() ?
    Bonjour à tous,

    J'ai déjà essayé d'aborder la question dans un sujet épinglé concernant les bonnes méthodes de programmation en PHP mais c'était noyé au milieu de tout le reste et c'est donc passé inaperçu. Pourtant je pense que ça pourrait être intéressant d'en parler donc je tente de lancer un sujet tout neuf pour ça

    Chaque fois que je me lance dans la conception d'un modèle objet en PHP, je me pose la même question : "comment je vais faire mes accesseurs et muttateurs ?".
    Est ce que j'utilise les méthodes magiques __get et __set (voir ici pour ceux qui ne connaissent pas) ou est ce que je passe par des méthodes "en dur" à l'ancienne dans le genre getXXX() setXXX('toto') ?

    Qu'utilisez vous et pourquoi ?

    Quels avantages et inconvénients voyez-vous à ces deux méthodes ?

  2. #2
    Membre Expert
    Avatar de Eusebe
    Inscrit en
    Mars 2006
    Messages
    1 992
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 992
    Par défaut
    Bonjour,

    Personnellement, par habitude prise dans d'autres langages, j'utilise mes propres méthodes. Ça permet au moins d'avoir un code clair, et de savoir si l'on passe par une méthode ou pas quand on accède à une propriété d'un objet (et donc éventuellement, ça permet de savoir si ça vaut le coup d'aller jeter un œil sur cette méthode).

    Pour les méthodes magiques, le seul intérêt que j'y vois pour l'instant (mais je ne me suis jamais vraiment penché dessus), c'est le fait de pouvoir rendre une propriété privée, pour ajouter des traitements à la consultation ou la modification, sans pour autant modifier le code qui utilise cette propriété...

  3. #3
    Membre chevronné
    Inscrit en
    Février 2005
    Messages
    419
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Février 2005
    Messages : 419
    Par défaut
    Ça permet au moins d'avoir un code clair, et de savoir si l'on passe par une méthode ou pas quand on accède à une propriété d'un objet
    Certaines chartes de codage (je pense notamment à la Zend à laquelle j'essaye de me tenir) imposent de préfixer les attributs et méthodes private/protected d'un _. Cela permet de faire la différence entre l'attribut appelé depuis l'extérieur avec traitements (via __get) ou brut depuis l'intérieur. ça permet de différencier l'appel direct d'un appel par l'accesseur magique.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    private $_id;
    public $nom;
     
    public function __get($attr)
    {
      if($attr == 'id') {
        return $this->_id;
      }
    }
    Un intérêt que je vois aussi à la méthode magique (même si en y réfléchissant bien je ne pense pas que ça soit utile sur beaucoup de cas concrets), c'est que quelque soit l'attribut demandé on peut effectuer une action.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public function __get($attr) {
      $this->monActionQuiVaFaireJeSaisPasQuoi(); // Pourquoi pas une vérification que l'objet est bien synchronisé avec une base
     
      if($attr == 'id') {
         return $this->_id;
      }
    }
    Or avec des getXXX setXXX classiques il aurait fallu appeler cette méthode à chaque fois. Bon comme je l'ai dis ça ne doit être utile que dans 2% des cas donc pas un argument très valable

    Un inconvénient aux méthodes magiques : on utilise des choses qui n'existent pas concrètement donc ça peut porter à confusion. En fait c'est pratique parce que ça peut laisser place à des automatismes intéressants, mais cette liberté apportée permet aussi de faire tout et n'importe quoi (vas y que je t'invente un attribut qui n'existe pas dans la classe et que ça marche quand même ...). Remarque, on peut aussi faire des getNimporteQuoi() ...
    Autre inconvénient (qui n'en sera sûrement pas un pour tout le monde) : les outils d'autocomplétion perdent les pédales puisqu'ils ne savent pas ce qui se passent dans les méthodes magiques.

  4. #4
    Membre chevronné

    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    317
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2006
    Messages : 317
    Par défaut
    Un des gros inconvénients de la méthode __get, __set, __call, c'est vraiment le suivi du code.

    En codant, je n'ai pas l'habitude de regarder les methodes get associé aux classes mais plutot à rechercher les assesseurs.

    Avantage :
    - on economise beaucoup de codes (faux avantage)
    - pouvoir rediriger la demande de variable sur un objet enfant.

    Inconvenient :
    - on met les attributs en public, on economise aussi beaucoup de code ^^
    - IDE ne referencant pas les assesseurs

    Neanmoins, si on est parfaitement clair dans ce qu'on fait (chose tres rare pour un codeur php), que l'on respecte toujours les memes conventions, on peut gagner beaucoup de temps avec les assesseurs magic et le call.

    Seulement, l'application devient enormément vulnérable à l'evolution de PHP.

  5. #5
    Membre chevronné
    Inscrit en
    Février 2005
    Messages
    419
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Février 2005
    Messages : 419
    Par défaut
    - on met les attributs en public, on economise aussi beaucoup de code ^^
    Je ne suis pas d'accord avec ça, si on passe par un accesseur (même magique), c'est pour pouvoir surcharger le comportement lors de l'accès (qu'il soit en lecture ou en écriture) et ajouter des traitements.
    Donc mettre l'attribut en public empêche ce genre de chose.
    L'utilisation n'est pas la même du tout.

    Pour le reste par contre je suis d'accord.

    Bien que pour les IDE il y a peut être une solution au niveau des commentaires (voir phpdocumentor et trucs du genre). Il semble y avoir un tag @prop qui permet de spécifier la liste des propriétés d'un objet. Mais je ne suis pas sûr que Zend studio l'interprète, elle n'est pas dans l'autocomplétion des comm. Mais bon ça ça ne concerne que ceux qui utilisent Zend

  6. #6
    Membre éprouvé Avatar de SirDarken
    Profil pro
    Développeur Web
    Inscrit en
    Février 2004
    Messages
    897
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services de proximité

    Informations forums :
    Inscription : Février 2004
    Messages : 897
    Par défaut
    Je n'ai pas fait d'objet en php (faute de temps mais j'aimerai!) mais pour moi il est clair que j'utilisera pas ce genre de 'combine', si j'ai besoin d'une chose je la code, sinon elle n'existe pas pour moi, et puis au moins si jamais dans une versiosn futures ils enlèvent ca je serai pas perdu ni troublé.

    Puis je sais pas ca fait un coté plus sérieux de tout écrire, quand je taper un peu de java (laché encore par faute de temps vive les journées de 48h) ca me semblait logique quasiment naturel d'ecrire les ascesseurs et mutateurs.

    Aprés voila je suis pas d'un niveau expert ou autre, juste un ptit dev mais pour moi c'est getXX() puis c'est tout, le pourquoi, comment, ta tord, ta raison je laisse ca aux ingénieurs , moi je tente de m'imposer le plus de contraintes pour être pros et c'est deja pas évident (ta tjrs une meilleure façon de ) alors pour une fois que je peux choisir dés le début autant prendre la bonne ligne.

  7. #7
    Expert confirmé
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Par défaut
    Citation Envoyé par Sylvain71 Voir le message
    Est ce que j'utilise les méthodes magiques __get et __set (voir ici pour ceux qui ne connaissent pas) ou est ce que je passe par des méthodes "en dur" à l'ancienne dans le genre getXXX() setXXX('toto') ?
    Réponse inévitable : ça dépend

    L'intérêt d'utiliser des champs privés & accesseurs plutôt que des champs publiques est qu'il possible d'associer du code à chaque opération de lecture/écriture effectuée sur ces champs. Ce code peut-être du code de validation implémentant une règle métier concernant un champ de l'objet (par exemple un accesseur setID($id) déclenchant une exception si l'id passé en paramètre n'est pas dans une plage fixée ou crée un doublon), ou différents effets de bord liés au changement de valeur du champ.

    A contrario, le code présent dans les méthodes magiques __get() et __set() ne peut être que générique, commun à tous les champs. Il faut donc privilégier les accesseurs spécifiques à chaque champ de l'objet.

    Les seules utilisations concrètes de __get() et de __set() que j'ai vues (en PHP et dans d'autres langages de script), sont la création "à la volée" de champs pour un objet donné (une instance), les pseudo-champs ainsi créés étant généralement stockées dans un tableau associatif appartenant à l'objet. Par contre, je ne les ai jamais vues utilisées pour accéder à des champs figurant dans la déclaration d'une classe.
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 448
    Par défaut
    Bon je vais encore faire vent contraire, mais moi je m'en sert pratiquement tout le temps. Parce que je trouve que c'est ... élégant.
    L'autre raison étant de pouvoir typer en entrée/sortie les valeurs.

    Après le souci c'est essentiellement pour les IDE avec auto complétion et support du code. Là sa passe complètement au travers..

    Sinon l'un ou l'autre, peu importe, mis à part pour la remarque de fladnag, si le code est clair, alors l"usage l'est aussi.
    Alors que ce soit des fonctions ou des propriétés magiques...

  9. #9
    Membre chevronné
    Inscrit en
    Février 2005
    Messages
    419
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Février 2005
    Messages : 419
    Par défaut
    GrandFather je ne suis pas vraiment d'accord avec toi lorsque tu dis
    A contrario, le code présent dans les méthodes magiques __get() et __set() ne peut être que générique, commun à tous les champs.
    Ou alors j'ai mal compris peut être.
    Mais le code présent dans les __get et __set peut ne pas être générique puisqu'on les conditionner pour qu'ils ne répondent qu'à tel ou tel nom d'attribut.

    Remarque maintenant que je dis ça je me rend compte que ça dépend ce qu'on entend par "générique"

    On peut faire du spécifique dans le sens où on exécutera que certains bouts de code selon l'attribut demandé. Mais ça oblige à faire des tests donc plus long. Après si c'est pas des tests de bourrins (généralement c'est des trucs du genre $attr == 'toto') ça n'a peut être pas beaucoup de conséquences.

    Pour répondre à Sir Darken :
    Puis je sais pas ca fait un coté plus sérieux de tout écrire, quand je taper un peu de java (laché encore par faute de temps vive les journées de 48h) ca me semblait logique quasiment naturel d'ecrire les ascesseurs et mutateurs.
    En fait au début je réagissais exactement comme toi, j'ai fais du java dans le passé et j'ai pris pour habitude de créer mes bons vieux getXXX et setXXX. J'ai donc fais l'impasse sur les __get et __set en me disant quand même que si ça avait été ajouté à PHP5 c'était sûrement qu'il y avait une bonne raison (d'ailleurs ça m'étonnerait qu'ils l'enlèvent dans les versions futures mais ça c'est une autre histoire). Et puis un jour pendant mes études je me suis rendu compte que la même chose se faisait un VB (enfin ... pas exactement mais un truc dans le genre, si il y a des adeptes du VB ici je suis à l'écoute car ce langage n'a jamais vraiment été mon fort et en plus c'est loin ).
    De plus il me semble qu'une discussion a été lancée sur le forum java quand à la mise en place d'un système similaire pour ce langage.

    C'est donc pour ça que je ramène cette question sur le tapis en PHP. L'évolution des langages semble chercher à amener cette nouveauté de partout (enfin partout ... façon de dire ). Donc est ce bien est ce mal ? Est ce qu'on a tendance à dire que c'est mal parce qu'on est attachés à nos bonnes vieilles méthodes et qu'on ne cherche pas plus loin ? Est ce qu'ils ont été créé dans un but bien spécifique ? Pourquoi le soleil ? N'est ce pas un bon moyen pour canaliser tous les passages de l'extérieur à l'intérieur de la classe en un seul et même point ?

    En fait pour le moment je suis ni pour ni contre. Mais je suis intrigué par ces méthodes magiques et vu que je me lance dans un projet qui risque d'être assez conséquent au final j'aimerais bien poser les plus et les moins de chaque solution.

  10. #10
    Expert confirmé
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 55

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Par défaut
    Citation Envoyé par Sylvain71 Voir le message
    On peut faire du spécifique dans le sens où on exécutera que certains bouts de code selon l'attribut demandé. Mais ça oblige à faire des tests donc plus long. Après si c'est pas des tests de bourrins (généralement c'est des trucs du genre $attr == 'toto') ça n'a peut être pas beaucoup de conséquences.
    Cela voudrait dire que dans ton __set() tu aurais un switch () qui lancerait ces traitements en fonction du nom du champ passé en paramètre... Je ne suis pas convaincu du gain en terme de simplicité, de lisibilité et de performances par rapport à des accesseurs, sans compter que cela oblige à écrire en plus le code qui va gérer le cas où le paramètre ne correspond à aucun champ déclaré dans la classe.

    Je pense que l'objectif premier de ces méthodes est de rendre les classes "dynamiques" du point de vue du code client de ces classes, de permettre d'ajouter des champs ou des méthodes en cours d'exécution. Ce n'est évidemment qu'une illusion, les classes en PHP ne sont pas (encore) dynamiques, et derrière on a un simple traitement procédural.
    Citation Envoyé par Sylvain71
    En fait pour le moment je suis ni pour ni contre. Mais je suis intrigué par ces méthodes magiques et vu que je me lance dans un projet qui risque d'être assez conséquent au final j'aimerais bien poser les plus et les moins de chaque solution.
    Attention à la tentation du "marteau en or" : tu évalueras la possibilité d'utiliser ces méthodes "magiques" quand tu seras face à un besoin spécifique qui les justifiera par rapport à d'autres solutions, ne fais pas l'inverse (leur trouver une utilisation sans nécessité préalable).
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

Discussions similaires

  1. PDT : code completion sur __get()
    Par djibxav dans le forum Eclipse PHP
    Réponses: 0
    Dernier message: 04/05/2009, 12h29
  2. __GET & __SET
    Par J_Lennon dans le forum Langage
    Réponses: 7
    Dernier message: 31/12/2008, 18h42
  3. [POO] magic function __set/__get
    Par WG614 dans le forum Langage
    Réponses: 6
    Dernier message: 18/08/2008, 17h50
  4. [POO] __Get / __Set et héritage
    Par kendras dans le forum Langage
    Réponses: 4
    Dernier message: 06/12/2007, 14h51
  5. [EJB2.1 Entity] enlever de ma facade distante les méthodes addXX/getXX.. de mes entity beans locales
    Par cyrilforever dans le forum Java EE
    Réponses: 9
    Dernier message: 04/01/2007, 18h37

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