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] Comment se fait-il que mon attribut soit reconnu ? [PHP 5.2]


Sujet :

Langage PHP

  1. #1
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 096
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 096
    Points : 944
    Points
    944
    Par défaut [POO] Comment se fait-il que mon attribut soit reconnu ?
    Bonjour a tous,
    Je me lance dans l'Orienté objet et j'ai lu qu'on pouvait donner une valeur a un attribut de la maniere suivante:
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    $nom->attribut = 'cpoucou';
    grace à
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	public function __set($name, $value){
    		echo 'Defini '.$name.' a : '.$value.'<br />';
    		$this->$name=$value;
    	}
    j'ai aussi dans ma classe ceci
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class nom{
    private $attribut;
    	public function __set($name, $value){
    		echo 'Defini '.$name.' a : '.$value.'<br />';
    		$this->$name=$value;
    	}
    }
    Donc si je fais
    ma fonction __set doit me retourner
    'Defini attribut a : coucou
    Mon problème est le suivant.
    Si je fais maintenanr
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    $nom->titi = 'cpoucou';
    ceci s'affiche
    'Defini titi a :
    Alors que je n'ai jamais défini titi de la maniere suivante
    Normalement , mais si je mets
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    $nom->titi = 'cpoucou';
    Je devrais avoir un message d'erreur car elle n'a jamais été déclaré , ou alors rien ne devrait s'afficher non?
    Il ne suffit pas de tout savoir. Vouloir et persévérer, c'est déjà presque tout!

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 319
    Points : 351
    Points
    351
    Par défaut
    Salut !

    J'aimerais déjà te poser une question : pourquoi utilises-tu cette méthode magique __set ? Les cas d'usage sont somme toute assez rares et je doute que, si tu débutes en OO, tu en aies déjà besoin...

    __set, comme le dit le manuel, intervient pour les attributs qui ne sont pas accessibles (ne pas exister étant un cas évident de non-accsesibilité).

    Lorsqu'on utilise __set pour faire quelque chose de précis il y a fort à parier qu'on ait aussi besoin de __get.

    Bref, peut-être vaudrait-il mieux cerner tes besoins dans un premier temps

  3. #3
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 496
    Points : 12 596
    Points
    12 596
    Par défaut
    Tu utilises une des méthodes magiques de PHP le __set permet justement de traiter les cas qui n'existe pas.

    Donc dès que que tu donne une valeur à un attribut qui n'a pas de méthode setter, alors la méthode magique __set (que tu as définis) rentre en jeu.

  4. #4
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 096
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 096
    Points : 944
    Points
    944
    Par défaut
    Bonjour a Oscar Hiboux et Maitre Pilos ,
    Merci pour vos réponses.
    J'aimerais déjà te poser une question : pourquoi utilises-tu cette méthode magique __set ?
    Ben je ne sais pas trops quoi te répondre. Je lis un livre super dont l'un des premier chapitre parlait de cette classe magique. J'ai donc essayé avec ceci.
    Etant donné que je debut, me conseillerais tu de continuer avec ou pas?
    Tu utilises une des méthodes magiques de PHP le __set permet justement de traiter les cas qui n'existe pas.

    Donc dès que que tu donne une valeur à un attribut qui n'a pas de méthode setter, alors la méthode magique __set (que tu as définis) rentre en jeu.
    Donc dans ce cas las, a quoi ca me sert de déclarer tous ces attributs??
    Code PHP : 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
     
    class Field extends Check{
    	private $accept;
    	private $accesskey;
    	private $align;
    	private $alt;
    	private $border;
    	private $checked;
    	private $dir;
    	private $disabled;
    	private $height;
    	private $hspace;
    	private $lang;
    	private $maxlength;
    	private $onblur;
    	private $onchange;
    	private $ondblclick;
    	private $onfocus;
    	private $onkeydown;
    	private $onkeypress;
    	private $onkeyup;
    [....]
    Il ne suffit pas de tout savoir. Vouloir et persévérer, c'est déjà presque tout!

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 319
    Points : 351
    Points
    351
    Par défaut
    Comme je te le disais juste avant : les cas d'usage des "méthodes magiques" sont très rares. Si tu t'intéresses à la programamtion objet en PHP je te conseille fortement de les laisser de côté pour le moment, oui !

    Pour le reste, à quoi ça sert d'écrire tout ça ? Eh bien c'est simple : il s'agit de "décrire" ce que sont tes objets, et c'est ainsi qu'on le fait en PHP. Écrire une classe c'est exposer tout ce dont elle sera capable, pour elle même ou pour le public.

    Bon courage !

  6. #6
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 096
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 096
    Points : 944
    Points
    944
    Par défaut
    Ok, merci Hiboux.
    J'ai un peu du mal a comprendre pourquoi les classe magique sont à éviter, mais je vais suivre ton conseil et j'en suis sure que le décrouvrirai plus tard.

    Merci
    Il ne suffit pas de tout savoir. Vouloir et persévérer, c'est déjà presque tout!

  7. #7
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 096
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 096
    Points : 944
    Points
    944
    Par défaut
    Mais en fait, si laisse tomber mes fonction magique, je vais devoir passer toutes mes attribut en plublic, pour qu'ils puissent etre modifier depuis l'extérieur.
    Si je les laissaient en private, en utilisant les function magique, es-ce que j'augmenterai la sécurité de mon code?
    Il ne suffit pas de tout savoir. Vouloir et persévérer, c'est déjà presque tout!

  8. #8
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 096
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 096
    Points : 944
    Points
    944
    Par défaut
    MaitrePylos,
    j'ai un soucis par rapport a ta déclaration.
    J'ai supprimé , mes classes magique, soit __set et __get.

    J'ai ensuite fait ceci
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $nom->hhh='4';
    echo $nom->hhh;
    et j'ai 4 qui s'affiche alors que l'attribut "hhh" n'existe pas.
    Je ne comprends pas pourquoi je n'ai pas de message d'erreur, étant donné que je n'utilise pas de function magique
    Tu utilises une des méthodes magiques de PHP le __set permet justement de traiter les cas qui n'existe pas
    ?
    Il ne suffit pas de tout savoir. Vouloir et persévérer, c'est déjà presque tout!

  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
    Citation Envoyé par pierrot10
    J'ai ensuite fait ceci
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $nom->hhh='4';
    echo $nom->hhh;
    et j'ai 4 qui s'affiche alors que l'attribut "hhh" n'existe pas.
    C'est normal, Php permet de créer de nouvelles propriétés en dehors de la classe (sous entendu : sans même la déclarer).
    Ce comportement n'a strictement aucun rapport avec les méthodes magiques __get() et __set().

    A mon avis, il vaut mieux l'éviter.
    Faut juste se dire que, même si Php permet de faire plein de choses, énormément même, ce n'est pas pour autant qu'il faille le faire.
    En somme, Php permet de quasi tout faire, même les truc les plus tordus, c'est au codeur de bien coder.

    Petite remarque au passage.
    Je vois que tu déclare beaucoup de propriétés et méthodes en "private".
    Les "public", "protected" et "private" n'est pas un simple moyen de rendre plus ou moins sécurisé son code, c'est plus une déclaration pour définir la "portée" (ou visibilité/accessibilité) des propriétés et méthodes.
    Leur choix dépend du contexte, donc de là ou elles sont créés et de là où l'on souhaite qu'elles soient utilisées/accessibles dans le code.

    La déclaration "private" me semble un peu plus subtile, cela va un peu plus loin qu'on l'imagine, il doit y avoir une notion d'héritage, ou de classe étendue/dérivée.
    Le manuel le défini ainsi :
    Citation Envoyé par manuel Php
    L'accès aux éléments privés (private) est uniquement réservé à la classe qui les a définis.
    Elle est plus faite pour rendre inaccessible une propriété ou méthode d'une classe mère à une classe enfant (ou classe dérivée).
    Utiliser la portée "private" est donc bien plus rare que "protected" et "public".


    Au vu de ton code, utiliser "protected" sera bien plus adapté, et suffisant si le but est de rendre inaccessible une propriété ou méthode en dehors de la classe, et qu'il n'y pas de notion d'héritage.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  10. #10
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 496
    Points : 12 596
    Points
    12 596
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $nom->hhh='4';
    echo $nom->hhh;
    Effectivement cela fonctionne, mais cela n'a aucune incidence dans ta classe, puisque tu ne sais rien en faire(dans ta classe), cela équivaut à créer une variable.

    ceci donne le même résultat.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
    $nom='4';
    echo $nom;
    Mais en fait, si laisse tomber mes fonction magique, je vais devoir passer toutes mes attribut en plublic, pour qu'ils puissent etre modifier depuis l'extérieur.
    Si tu met tes attributs en privé, c'est que tu ne veut pas qu'elles soient modifier de l'extérieur, c'est le principe du private.


    Maintenant si tu veux pouvoir modifier un attribut private, il faut lui adjoindre les méthodes setter et getter (renseigne toi la dessus), et chaque attribut doit avoir ses propres méthodes (si tu veux modifier en dehors de la classe)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    private $accept;
     
    public function setAccept($value){
     
    $this->accept = $value;
    }
     
    public function getAccept(){
    return $this->accept ;
    }
    Tous les bons IDE te générerons automatiquement ces méthodes

  11. #11
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 096
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 096
    Points : 944
    Points
    944
    Par défaut
    Hello Tous!
    Un grabd mercis pour vos lumières!!!
    Je vais donc relire attentivement vos commentaires afin de faire le meilleurs au début.

    Je ne sais pas trop comment dfendre mon choix, mais je pense que je vais me pencher sur
    1) Ne plsu mettre mes attribut en private, mais plus tot en public
    2) Je vais aussi m'intéressé au methodes getAccept().

    En tout cas, mercis pour vos réponses
    Il ne suffit pas de tout savoir. Vouloir et persévérer, c'est déjà presque tout!

  12. #12
    Membre expert
    Avatar de ThomasR
    Homme Profil pro
    Directeur technique
    Inscrit en
    Décembre 2007
    Messages
    2 230
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2007
    Messages : 2 230
    Points : 3 972
    Points
    3 972
    Par défaut
    Bonjour,

    Utiliser les méthodes magiques __get et __set est souvent très utile, surtout pour éviter de passer par des fonctions de getting et setting ce qui rend le code laborieux à écrire. Bien que ces méthodes magiques offrent des performances miondre, c'est très pratique.

    Un appel à la méthode __set ne nécessite pas que le membre existe, tout comme c'est le cas sur la classe stdClass. Pour éviter ceci il suffit de vérifier que le membre voulu est bien membre de la classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class foo {
        private $bar = 'toto';
        public function __set($name, $val){
            if(property_exists(__CLASS__, $key)) $this->$key = $val;		
            else echo $name.' is not an existing property in '.__CLASS__;
        }
     
        public function __get($name){
            if(property_exists(__CLASS__, $key)) return $this->$key;    	    		
            return;
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $foo = new foo;
    $foo->bar = 'un truc';
    echo $foo->bar;
     
    $foo->baar = 'a second truc';
    Surtout, ne pas met pas tes attributs public si tu ne souhaites pas qu'on puisse les valoriser avec n'importe quoi ! Ca n'a pas de sens... et cela va à l'encontre de la POO et de son encapsulation.

  13. #13
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 096
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 096
    Points : 944
    Points
    944
    Par défaut
    Ok excellent pour ton post.
    Je me demandais aussi comment vérifier qu'un attribut existe, dans sa classe!! et c'est que tu l'écris .

    Aussi donc je conclus qu'il est préférable de privilégier le mode protected avant public et ensuite private.
    Il ne suffit pas de tout savoir. Vouloir et persévérer, c'est déjà presque tout!

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 319
    Points : 351
    Points
    351
    Par défaut
    [QUOTE=ThomasR;4994603]Utiliser les méthodes magiques __get et __set est souvent très utile, surtout pour éviter de passer par des fonctions de getting et setting ce qui rend le code laborieux à écrire. Bien que ces méthodes magiques offrent des performances miondre, c'est très pratique.[/code]

    Voilà, ça résume bien.

    Ceci étant dit je persiste : ce n'est pas le plus important à apprendre lorsqu'on débute en orienté objet. C'est d'ailleurs, si je ne m'abuse, un trait bien particulier à PHP et dans une majorité de langages OO conventionnels on sera toujours obligé de décrire intégralement les objets, y compris les accesseurs (set/get). Il vaut mieux s'y faire dès le début !

  15. #15
    Membre expert
    Avatar de ThomasR
    Homme Profil pro
    Directeur technique
    Inscrit en
    Décembre 2007
    Messages
    2 230
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2007
    Messages : 2 230
    Points : 3 972
    Points
    3 972
    Par défaut
    Ceci étant dit je persiste : ce n'est pas le plus important à apprendre lorsqu'on débute en orienté objet.
    Entièrement d'accord
    C'est d'ailleurs, si je ne m'abuse, un trait bien particulier à PHP
    Tout à fait
    et dans une majorité de langages OO conventionnels on sera toujours obligé de décrire intégralement les objets, y compris les accesseurs (set/get). Il vaut mieux s'y faire dès le début !
    Partiellement, dans le langage .net, il existe la structure "Property" qui permet de définir et le getter, et le setter, d'un attribut par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class TimePeriod
    {
        private double seconds;
     
        public double Hours
        {
            get { return seconds / 3600; }
            set { seconds = value * 3600; }
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    TimePeriod p = new TimePeriod();
    p.Hours = 2;
    Reponse.Write(p.Hours);
    Je trouve cette synthaxe vraiment sympa.

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    319
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2006
    Messages : 319
    Points : 351
    Points
    351
    Par défaut
    Ah, sympa, oui !

    Il y a aussi une syntaxe spéciale en JavaScript aussi, mais elle n'est pas encore véritablement supportée / utilisée.

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

Discussions similaires

  1. [PHP 5.3] [POO] Comment afficher le nom de l'attribut et non pas sa valeur
    Par pierrot10 dans le forum Langage
    Réponses: 5
    Dernier message: 28/03/2010, 21h59
  2. Commenf faire pour que mon réseau soit en 1 GB ?
    Par Yepazix dans le forum Hardware
    Réponses: 9
    Dernier message: 09/03/2010, 19h04
  3. Petite aide pour que mon appli soit utilisable via un VPN
    Par FredericB dans le forum C++Builder
    Réponses: 0
    Dernier message: 23/09/2007, 18h12

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