[POO] self:: ou $this-> ?

Mammouth du PHP | 1668 Messages

07 juin 2008, 16:48

Bonjour, j'ai une question en POO,
Quel est la différence entre slef:: et $this-> ? Ont-ils le même usage ? Lequel vaut-il mieu utiliser ?

Moi, j'ai toujours eu l'habitude de faire comme ça :
$this->variable;
self::fonction($arguments);
Hors j'aI pût lire ça :
$this->fonction($arguments);
As-t-on le droit ? Ai-je mal compris la POO ?
"À ceux qui poursuivent leurs rêves et se spécialisent dans l'impossible" Joseph Kong

10 ans de PHP, déjà.

"moi jtrouve que katagoto il déchire!" Nagol

ViPHP
ViPHP | 2287 Messages

07 juin 2008, 16:58

Ce n'est pas la même chose : dans un cas, tu appelles une méthode de l'objet ( $this->truc() ), dans l'autre cas, tu appelles statiquement une méthode de classe (l'équivalent d'un appel de fonction classique php).

L'avantage de programmer en objet est de ne pas avoir 12 arguments à transmettre à une méthode puisque cette méthode est rattachée à l'objet (et qu'en explorant l'objet et ses propriétés, tu peux retrouver à peu près toutes les variables contextuelles dont la méthode a besoin pour agir).

En clair, quand tu appelles $this->truc(), la variable $this est disponible dans la méthode truc() que tu éxécutes. Quand tu l'appelles en self::truc(), elle ne l'est pas, et si tu l'utilises tu vas avoir droit à une magnifique erreur PHP.
if(!@work()){ Nespresso(); } else { what(); }
______________________________

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

08 juin 2008, 12:28

Je vais probablement un peu répéter ce qu'à dit Calimero, mais personnellement je verrais plutôt l'approche sous cet angle :

- "$this" fait référence à l'instance courrante de l'objet. C'est à dire que l'on a obligatoirement fait un "new" pour obtenir une nouvelle instance spécifique de la classe, et c'est à celle-ci qu'on fait appel.
- "self" en revanche équivaut à la classe dans son ensemble et non pas à une instance spécifique.

La différence se fait donc au niveau de l'accès aux attributs et méthodes qui peut être fait de manière statique (pouvoir y accéder sans avoir besoin d'instancier la classe) ou pas.

Les exemples et explications de la doc sur le mot clé static te donneront peut être une meilleure visibilité de leur fonctionnement et leur utilisation :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Mammouth du PHP | 1668 Messages

08 juin 2008, 14:18

J'y vois plus claire, merci :wink:
"À ceux qui poursuivent leurs rêves et se spécialisent dans l'impossible" Joseph Kong

10 ans de PHP, déjà.

"moi jtrouve que katagoto il déchire!" Nagol

Mammouth du PHP | 965 Messages

11 août 2008, 16:14

Je rajoute une petite question : ce n'est donc utile que pour les variables ou méthodes statiques d'une classe ?

je veux dire utiliser self:: permet d'accéder a une méthode ou a un attribut (membre = attribut) déclarer en static sans avoir a instancier la classe uniquement.

et $this-> oblige a instancier la classe pour utiliser ces même fonctions.

Donc instancier une classe sers pour ses méthodes __construct, __autoload uniquement ?

Et donc un attribut ou une méthode servent à quoi au final si il ne peut pas être utiliser dans une même classe avec le $this-> ?

<patapay>

Mammouth du PHP | 1668 Messages

11 août 2008, 17:13

en gros oui, c'est un sorte de namespace...
"À ceux qui poursuivent leurs rêves et se spécialisent dans l'impossible" Joseph Kong

10 ans de PHP, déjà.

"moi jtrouve que katagoto il déchire!" Nagol

ViPHP
ViPHP | 5924 Messages

11 août 2008, 17:15

C'est pourtant simple. Le mot clé self donne accès à toutes les propriétés de la classe elle-même, à savoir les constantes, toutes les variables statiques (on pourraît dire communes à tous les objets, mais en réalité, cela signifie propriétés de la classe), ou méthodes statiques. Typiquement on dira que les méthodes et attributs statiques, appelés par self, s'appliquent à la classe elle même.
$this s'applique à l'objet lui même, à avoir que chaque objet va avoir ses propres données, et les méthodes qui y accèderont traiteront les données de cet objet spécifiquement. Quand on avec appellera $this, on se placera dans un contexte objet, c'est à dire que la méthode que l'on appelle travaille sur l'objet.
Elle est là la grosse subtilité, il faut savoir faire la part entre les deux, à savoir que dans un contexte objet (dans une méthode non statique), on a accès aux données d'un enregistrement, mais aussi, via le mot clé self, aux entités de la classe, parce que l'objet appartient à une classe. Lorsque l'on est dans une méthode statique, on n'a plus accès au contexte objet (donc au mot clé $this), puisque le contexte courant n'est plus associé à un objet précis, mais à la classe elle même.

Donc les méthodes __construct, et la majorité des méthodes magiques, ne servent qu'en contexte objet, mais le contexte objet ne sert pas qu'à cela, puisque toute méthode qui n'est pas déclarée static est en réalité une méthode d'objet, exécutée donc dans un contexte objet.
Quant à __autoload, c'est une fonction, non une méthode, elle n'a donc rien à voir avec notre réflexion courante...

ViPHP
ViPHP | 4674 Messages

11 août 2008, 23:52

Hey :),
en gros oui, c'est un sorte de namespace...
Sékil ne l'a pas dit (posté à 2mn d'intervalle aussi ;-)), mais c'est strictement faux. Ça n'a rien à voir.
Les espaces de nom (ou namespaces) servent à la hiérarchisation des classes entre elles, et non pas au contexte classe/objet.

Si vous n'avez pas compris ce qu'a dit Sékil, relisez calmement ;-). Il a dit l'essentiel, et c'est très juste, même si j'ai conscience que ça peut être un peu rebutant pour des débutants. N'hésitez pas à poser des questions.
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Mammouth du PHP | 1668 Messages

12 août 2008, 12:57

Hey :),
en gros oui, c'est un sorte de namespace...
Sékil ne l'a pas dit (posté à 2mn d'intervalle aussi ;-)), mais c'est strictement faux. Ça n'a rien à voir.
Les espaces de nom (ou namespaces) servent à la hiérarchisation des classes entre elles, et non pas au contexte classe/objet.
On va dire que c'est faux en effet, mais c'est un regroupement de données/fonctions, deplus, les espaces noms peuvent être aggrandit sans héritage...

Voilà.
"À ceux qui poursuivent leurs rêves et se spécialisent dans l'impossible" Joseph Kong

10 ans de PHP, déjà.

"moi jtrouve que katagoto il déchire!" Nagol

ViPHP
ViPHP | 4674 Messages

12 août 2008, 13:30

Je ne comprends rien à ce que tu racontes. Il n'est pas du tout question d'espace de nom ici, alors ça ne sert à rien d'en parler …
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).