Je vais demander quelle est la différence entre: cont A; $ this-> A et self :: A
timmz
Réponses:
1728
Réponse courte
Utilisez $thispour faire référence à l'objet actuel. Utilisez selfpour faire référence à la classe actuelle. En d'autres termes, utilisez
$this->memberpour les membres non statiques, utilisez self::$memberpour les membres statiques.
Réponse complète
Voici un exemple d' utilisation correcte de $thiset selfpour les variables membres non statiques et statiques:
Voici un exemple de polymorphisme avec $thispour les fonctions membres:
<?phpclass X {function foo(){
echo 'X::foo()';}function bar(){
$this->foo();}}class Y extends X {function foo(){
echo 'Y::foo()';}}
$x =new Y();
$x->bar();?>
Voici un exemple de suppression du comportement polymorphe à l'aide selfde fonctions membres:
<?phpclass X {function foo(){
echo 'X::foo()';}function bar(){self::foo();}}class Y extends X {function foo(){
echo 'Y::foo()';}}
$x =new Y();
$x->bar();?>
L'idée est d' $this->foo()appeler la foo()fonction membre de quel que soit le type exact de l'objet actuel. Si l'objet est de type X, il appelle donc X::foo(). Si l'objet est de type Y, il appelle Y::foo(). Mais avec self :: foo (), X::foo()est toujours appelé.
Cette réponse est trop simpliste. Comme indiqué dans d'autres réponses, selfest utilisé avec l'opérateur de résolution de portée ::pour faire référence à la classe actuelle; cela peut être fait à la fois dans des contextes statiques et non statiques. De plus, il est parfaitement légal d'utiliser $thispour appeler des méthodes statiques (mais pas pour référencer des champs).
Artefacto
50
Pensez également à utiliser static :: au lieu de :: self si vous êtes sur 5.3+. Cela peut vous causer des maux de tête incalculables sinon, consultez ma réponse ci-dessous pour savoir pourquoi.
Sqoo
25
-1. Cette réponse est trompeuse, lisez les autres réponses pour plus d'informations.
Pacerier
6
C'est peut-être trop simplifié, mais cela a répondu à ma question de niveau de base sans faire exploser ma tête. J'ai obtenu plus d'informations que j'ai trouvées plus bas, mais pour l'instant j'essayais juste de comprendre pourquoi j'ai frappé mes attributs de classe avec $ this-> attrib et les constantes de classe avec self :: constant. Cela m'a aidé à mieux comprendre
MydKnight
Et alors $this::?
James
742
Le mot-clé self ne fait PAS simplement référence à la «classe actuelle», du moins pas d'une manière qui vous limite aux membres statiques. Dans le contexte d'un membre non statique, selffournit également un moyen de contourner la vtable ( voir wiki sur vtable ) pour l'objet actuel. Tout comme vous pouvez utiliser parent::methodName()pour appeler la version parent d'une fonction, vous pouvez également appeler self::methodName()pour appeler l'implémentation de classes actuelle d'une méthode.
Bonjour, je suis Ludwig le geek
Au revoir de Ludwig la personne
sayHello()utilise le $thispointeur, donc la vtable est invoquée pour appeler Geek::getTitle().
sayGoodbye()utilise self::getTitle(), donc la vtable n'est pas utilisée et Person::getTitle()est appelée. Dans les deux cas, nous avons affaire à la méthode d'un objet instancié, et avons accès au $thispointeur dans les fonctions appelées.
Cette réponse serait encore meilleure si vous commenciez par une règle générale plutôt que par une exception. C'est une question de style, pas d'expertise technique. C'est le meilleur exemple que j'ai jamais vu de la différence entre self :: et $ this->, mais c'est dommage de le cacher en réfutant d'abord une notion.
adjwilli
3
@adjwilli: Pourquoi ce mauvais style? Cela n'éveille-t-il pas la conscience si l'attente (thèse) du PO est d'abord désapprouvée (antithèse) puis l'explication est donnée comme synthèse?
hakre
1
Je trouve que la "classe actuelle" est vraiment problématique. Comme cette combinaison de mots peut être comprise à la fois comme "la classe où selfse trouve" / "la définition de classe, elle fait littéralement partie de" ainsi que "la classe de l'objet" (qui serait en fait static).
Jakumi
Et alors $this::?
James
1
@James - il n'y a aucune bonne raison d'utiliser $this::; tous les cas possibles sont déjà couverts par des syntaxes plus couramment utilisées. Selon ce que vous voulez dire, l' utilisation $this->, self::ou static::.
ToolmakerSteve
460
NE PAS UTILISER self::, utiliserstatic::
Il y a un autre aspect de self :: qui mérite d'être mentionné. Désagréablement self::fait référence à la portée au point de définition et non au point d'exécution . Considérez cette classe simple avec deux méthodes:
classPerson{publicstaticfunction status(){self::getStatus();}protectedstaticfunction getStatus(){
echo "Person is alive";}}
Si nous appelons, Person::status()nous verrons "La personne est vivante". Considérez maintenant ce qui se passe lorsque nous créons une classe qui hérite de ceci:
classDeceasedextendsPerson{protectedstaticfunction getStatus(){
echo "Person is deceased";}}
En appelant, Deceased::status()nous nous attendrions à voir «La personne est décédée», mais ce que nous voyons est «La personne est vivante», car la portée contient la définition de la méthode d'origine lorsque l'appel à a self::getStatus()été défini.
PHP 5.3 a une solution. L' static::opérateur de résolution implémente la "liaison statique tardive", ce qui est une façon élégante de dire qu'elle est liée à la portée de la classe appelée. Modifiez la ligne status()pour static::getStatus()et les résultats sont ce que vous attendez. Dans les anciennes versions de PHP, vous devrez trouver un kludge pour ce faire.
"En appelant Deceased :: status (), nous nous attendrions à voir" La personne est décédée "". Non. Il s'agit d'un appel de fonction statique, il n'y a donc pas de polymorphisme impliqué.
cquezel
2
De tous les défauts de PHP, je ne pense pas que ce soit fou du tout. Sinon, comment permettraient-ils aux codeurs de désigner des méthodes sur la classe actuelle (au lieu de les rechercher dans la table virtuelle)? S'ils l'avaient nommé différemment (peut-être avec des traits de soulignement principaux), alors les gens qui veulent cette fonctionnalité la critiqueraient pour être laide. Sinon, quel que soit le nom sensé qu'ils pourraient utiliser, il semble qu'il y aurait toujours des gens facilement confus qui le critiqueraient pour être un comportement "insensé", probablement inconscient du fonctionnement même de la répartition des méthodes.
TNE
2
L'exemple me semble déroutant: je vois la getStatusméthode comme celle que j'appellerais pour une instance de classe, pas pour une classe.
Jānis Elmeris
1
@Sqoo - dire "NE PAS UTILISER self ::, use static ::" est un argument étrange à faire - ce n'est délibérément pas la même opération. Je pense que le point que vous faites valoir est "il est plus clair si vous utilisez le nom de classe réel" MyClass :: ", plutôt que" self :: " . Autrement dit, si vous voulez le comportement de self::, vous pouvez l'obtenir, moins prêter à confusion, en utilisant le nom de classe spécifique, par exemple MyClass::.
ToolmakerSteve
248
Pour vraiment comprendre de quoi nous parlons lorsque nous parlons de selfversus $this, nous devons réellement creuser ce qui se passe au niveau conceptuel et pratique. Je ne pense pas que l'une des réponses le fasse correctement, alors voici ma tentative.
Commençons par parler de ce qu'est une classe et un objet .
Classes et objets, conceptuellement
Alors, qu'est - ce qu'une classe ? Beaucoup de gens le définissent comme un plan directeur ou un modèle pour un objet. En fait, vous pouvez en savoir plus sur les classes en PHP ici . Et dans une certaine mesure, c'est ce que c'est vraiment. Regardons une classe:
Comme vous pouvez le constater, il y a une propriété sur cette classe appelée $nameet une méthode (fonction) appelée sayHello().
Il est très important de noter que la classe est une structure statique. Ce qui signifie que la classe Person, une fois définie, est toujours la même partout où vous la regardez.
Un objet d'autre part est ce qu'on appelle une instance d'une classe. Cela signifie que nous prenons le «plan directeur» de la classe et que nous l'utilisons pour faire une copie dynamique. Cette copie est désormais spécifiquement liée à la variable dans laquelle elle est stockée. Par conséquent, toute modification apportée à une instance est locale à cette instance.
$bob =newPerson;
$adam =newPerson;
$bob->name ='Bob';
echo $adam->name;// "my name"
Nous créons de nouvelles instances d'une classe en utilisant l' newopérateur.
Par conséquent, nous disons qu'une classe est une structure globale et un objet est une structure locale. Ne vous inquiétez pas de cette drôle de ->syntaxe, nous allons y revenir un peu.
Une autre chose dont nous devrions parler, c'est que nous pouvons vérifier si une instance est une instanceofclasse particulière: $bob instanceof Personqui retourne un booléen si l' $bobinstance a été créée en utilisant la Personclasse, ou un enfant de Person.
Définition de l'État
Examinons donc un peu ce que contient réellement une classe. Il y a 5 types de "choses" qu'une classe contient:
Propriétés - Considérez-les comme des variables que chaque instance contiendra.
classFoo{public $bar =1;}
Propriétés statiques - Considérez-les comme des variables partagées au niveau de la classe. Cela signifie qu'ils ne sont jamais copiés par chaque instance.
classFoo{publicstatic $bar =1;}
Méthodes - Ce sont des fonctions que chaque instance contiendra (et fonctionnera sur les instances).
classFoo{publicfunction bar(){}}
Méthodes statiques - Ce sont des fonctions qui sont partagées dans toute la classe. Ils ne fonctionnent pas sur les instances, mais uniquement sur les propriétés statiques.
classFoo{publicstaticfunction bar(){}}
Constantes - Constantes résolues par classe. Ne pas aller plus loin ici, mais en ajoutant pour être complet:
classFoo{const BAR =1;}
Donc, fondamentalement, nous stockons des informations sur la classe et le conteneur d'objets en utilisant des "astuces" sur l' électricité statique qui identifient si les informations sont partagées (et donc statiques) ou non (et donc dynamiques).
État et méthodes
A l'intérieur d'une méthode, l'instance d'un objet est représentée par la $thisvariable. L'état actuel de cet objet est là, et la mutation (modification) de toute propriété entraînera une modification de cette instance (mais pas des autres).
Si une méthode est appelée statiquement, la $thisvariable n'est pas définie . En effet, aucune instance n'est associée à un appel statique.
La chose intéressante ici est de savoir comment les appels statiques sont effectués. Parlons donc de la façon dont nous accédons à l'État:
État d'accès
Alors maintenant que nous avons enregistré cet état, nous devons y accéder. Cela peut devenir un peu délicat (ou bien plus qu'un peu), alors divisons cela en deux points de vue: de l'extérieur d'une instance / classe (disons à partir d'un appel de fonction normal ou de la portée globale) et à l'intérieur d'une instance / classe (à partir d'une méthode sur l'objet).
De l'extérieur d'une instance / classe
De l'extérieur d'une instance / classe, nos règles sont assez simples et prévisibles. Nous avons deux opérateurs, et chacun nous dit immédiatement si nous avons affaire à une instance ou à une classe statique:
->- objet-opérateur - Ceci est toujours utilisé lorsque nous accédons à une instance.
$bob =newPerson;
echo $bob->name;
Il est important de noter que l'appel Person->foon'a pas de sens (puisqu'il Persons'agit d'une classe et non d'une instance). Par conséquent, c'est une erreur d'analyse.
::- scope-resolution-operator - Ceci est toujours utilisé pour accéder à une propriété ou une méthode statique de classe.
echo Foo::bar()
De plus, nous pouvons appeler une méthode statique sur un objet de la même manière:
echo $foo::bar()
Il est extrêmement important de noter que lorsque nous faisons cela de l'extérieur , l'instance de l'objet est masquée de la bar()méthode. Cela signifie que c'est exactement la même chose que la course:
$class = get_class($foo);
$class::bar();
Par conséquent, $thisn'est pas défini dans l'appel statique.
De l'intérieur d'une instance / classe
Les choses changent un peu ici. Les mêmes opérateurs sont utilisés, mais leur signification devient nettement floue.
L' opérateur d'objet-> est toujours utilisé pour effectuer des appels à l'état d'instance de l'objet.
L'appel Foo::bar()appellera la baz()méthode de manière statique et ne$this sera donc pas rempli. Il convient de noter que dans les versions récentes de PHP (5.3+), cela déclenchera une E_STRICTerreur, car nous appelons des méthodes non statiques de manière statique.
Dans un contexte d'instance
Dans un contexte d'instance, en revanche, les appels effectués à l'aide de ::dépendent du destinataire de l'appel (la méthode que nous appelons). Si la méthode est définie comme static, alors elle utilisera un appel statique. Si ce n'est pas le cas, il transmettra les informations d'instance.
Ainsi, en regardant le code ci-dessus, l'appel $foo->bar()reviendra true, car l'appel "statique" se produit à l'intérieur d'un contexte d'instance.
Ça a du sens? Je ne le pensais pas. C'est confu.
Mots-clés raccourcis
Parce que tout lier ensemble en utilisant des noms de classe est plutôt sale, PHP fournit 3 mots-clés de "raccourci" de base pour faciliter la résolution de la portée.
self- Cela fait référence au nom de classe actuel. C'est self::baz()la même chose que Foo::baz()dans la Fooclasse (n'importe quelle méthode).
parent - Cela fait référence au parent de la classe actuelle.
static- Il s'agit de la classe appelée. Grâce à l'héritage, les classes enfants peuvent remplacer les méthodes et les propriétés statiques. Ainsi, les appeler à l'aide staticd'un nom de classe nous permet de déterminer d'où vient l'appel, plutôt que le niveau actuel.
Exemples
La façon la plus simple de comprendre cela est de commencer à regarder quelques exemples. Choisissons une classe:
Maintenant, nous examinons également l'héritage ici. Ignorez un instant qu'il s'agit d'un mauvais modèle d'objet, mais regardons ce qui se passe lorsque nous jouons avec ceci:
Ainsi, le compteur d'ID est partagé entre les deux instances et les enfants (parce que nous l'utilisons selfpour y accéder. Si nous l'utilisions static, nous pourrions le remplacer dans une classe enfant).
var_dump($bob->getName());// Bob
var_dump($adam->getName());// Adam
var_dump($billy->getName());// child: Billy
Notez que nous exécutons la méthode d' Person::getName()instance à chaque fois. Mais nous utilisons le parent::getName()pour le faire dans l'un des cas (le cas des enfants). C'est ce qui rend cette approche puissante.
Mot de prudence # 1
Notez que le contexte d'appel est ce qui détermine si une instance est utilisée. Donc:
Maintenant, c'est vraiment bizarre ici. Nous appelons une classe différente, mais celle $thisqui est transmise à la Foo::isFoo()méthode est l'instance de $bar.
Cela peut provoquer toutes sortes de bugs et WTF-ery conceptuel. Donc , je suggère fortement d' éviter l' ::opérateur à partir de méthodes d'instance sur quoi que ce soit , sauf ces trois mots - clés « raccourci » virtuels ( static, selfet parent).
Mot de prudence # 2
Notez que les méthodes et propriétés statiques sont partagées par tous. Cela en fait essentiellement des variables globales. Avec tous les mêmes problèmes que les globaux. Donc, j'hésiterais vraiment à stocker des informations dans des méthodes / propriétés statiques à moins que vous ne soyez à l'aise avec le fait qu'elles soient vraiment globales.
Mot de prudence # 3
En général, vous voudrez utiliser ce que l'on appelle la liaison statique tardive en utilisant staticau lieu de self. Mais notez que ce n'est pas la même chose, donc dire "toujours utiliser à la staticplace de selfest vraiment à courte vue. Au lieu de cela, arrêtez-vous et pensez à l'appel que vous voulez faire et pensez si vous voulez que les classes enfants soient capables de remplacer cette résolution statique appel.
TL / DR
Dommage, revenez en arrière et lisez-le. C'est peut-être trop long, mais c'est aussi long car c'est un sujet complexe
TL / DR # 2
OK bien. En bref, selfest utilisé pour référencer le nom de la classe actuelle dans une classe, où as $thisfait référence à l' instance d' objet actuelle . Notez qu'il selfs'agit d'un raccourci copier / coller. Vous pouvez le remplacer en toute sécurité par le nom de votre classe, et cela fonctionnera bien. Mais $thisc'est une variable dynamique qui ne peut pas être déterminée à l'avance (et peut-être même pas votre classe).
TL / DR # 3
Si l'opérateur objet est utilisé ( ->), alors vous savez toujours que vous avez affaire à une instance. Si l'opérateur scope-resolution-operator est utilisé ( ::), vous avez besoin de plus d'informations sur le contexte (sommes-nous déjà dans un contexte d'objet? Sommes-nous en dehors d'un objet? Etc).
Word of Caution # 1: $ this ne sera pas défini lors de l'appel d'une méthode statique: 3v4l.org/9kr0e
Mark Achée
Eh bien ... $thisne sera pas défini si vous suivez les "normes strictes" et n'appelez pas de méthodes statiques qui ne sont pas définies comme statiques. Je vois le résultat que vous avez expliqué ici: 3v4l.org/WeHVM D'accord, vraiment bizarre.
Mark Achée
2
Après avoir lu la longue description complètement, je me sentais paresseux pour faire défiler à nouveau ci-dessus pour le voter. Je plaisante, je l'ai voté: D. Merci c'est très utile.
Mr_Green
3
serait bien d'ajouter une explication claire sur la différence entre self :: $ property et self :: property; Je pense que c'est assez déroutant aussi
Tommaso Barbugli
1
WoC # 1 se comporte différemment depuis PHP 7. Comme Foo::isFoo()on l'appelle statiquement, $thisne sera pas défini. C'est un comportement plus intuitif à mon avis. - Un autre résultat différent est donné s'il Bardevait s'étendre de Foo. Ensuite, l'appel Foo::isFoo()serait en fait dans le contexte de l'instance (non spécifique à PHP7).
Kontrollfreak
117
self(pas $ self) fait référence au type de classe, où as $thisfait référence à l' instance actuelle de la classe. selfest à utiliser dans les fonctions membres statiques pour vous permettre d'accéder aux variables membres statiques. $thisest utilisé dans les fonctions membres non statiques et est une référence à l'instance de la classe sur laquelle la fonction membre a été appelée.
Parce que thisc'est un objet, vous l'utilisez comme:$this->member
Parce que ce selfn'est pas un objet, c'est fondamentalement un type qui fait automatiquement référence à la classe actuelle, vous l'utilisez comme:self::member
$this-> est utilisé pour faire référence à une instance spécifique des variables d'une classe (variables membres) ou des méthodes.
Example:
$derek =newPerson();
$ derek est maintenant une instance spécifique de Person. Chaque personne a un prénom et un nom de famille, mais $ derek a un prénom et un nom de famille spécifiques (Derek Martin). Dans l'instance $ derek, nous pouvons les désigner comme $ this-> first_name et $ this-> last_name
ClassName :: est utilisé pour faire référence à ce type de classe, et à ses variables statiques, aux méthodes statiques. Si cela peut vous aider, vous pouvez mentalement remplacer le mot "statique" par "partagé". Parce qu'ils sont partagés, ils ne peuvent pas faire référence à $ this, qui fait référence à une instance spécifique (non partagée). Les variables statiques (ie statique $ db_connection) peuvent être partagées entre toutes les instances d'un type d'objet. Par exemple, tous les objets de base de données partagent une seule connexion (connexion $ statique).
Variables statiques Exemple:
Imaginez que nous avons une classe de base de données avec une seule variable membre: static $ num_connections; Maintenant, mettez ceci dans le constructeur:
function __construct(){if(!isset $num_connections || $num_connections==null){
$num_connections=0;}else{
$num_connections++;}}
Tout comme les objets ont des constructeurs, ils ont aussi des destructeurs, qui sont exécutés lorsque l'objet meurt ou n'est pas défini:
function __destruct(){
$num_connections--;}
Chaque fois que nous créons une nouvelle instance, cela augmentera notre compteur de connexions d'une unité. Chaque fois que nous détruisons ou cessons d'utiliser une instance, cela diminue le compteur de connexions d'une unité. De cette façon, nous pouvons surveiller le nombre d'instances de l'objet de base de données que nous utilisons avec:
echo DB::num_connections;
Parce que $ num_connections est statique (partagé), il reflétera le nombre total d'objets de base de données actifs. Vous avez peut-être vu cette technique utilisée pour partager des connexions de base de données entre toutes les instances d'une classe de base de données. Cela est dû au fait que la création de la connexion à la base de données prend beaucoup de temps, il est donc préférable d'en créer une seule et de la partager (c'est ce qu'on appelle un modèle Singleton).
Les méthodes statiques (c'est-à-dire View :: format_phone_number ($ digits) statiques publiques) peuvent être utilisées SANS d'abord instancier l'un de ces objets (c'est-à-dire qu'elles ne se réfèrent pas en interne à $ this).
Comme vous pouvez le voir, la fonction statique publique prettyName ne sait rien de l'objet. Cela fonctionne simplement avec les paramètres que vous transmettez, comme une fonction normale qui ne fait pas partie d'un objet. Pourquoi s'embêter, alors, si nous pouvions simplement ne pas l'avoir comme partie de l'objet?
Tout d'abord, attacher des fonctions aux objets vous aide à garder les choses organisées, vous savez donc où les trouver.
Deuxièmement, il empêche les conflits de noms. Dans un grand projet, il est probable que deux développeurs créent des fonctions getName (). Si l'un crée un ClassName1 :: getName () et que l'autre crée ClassName2 :: getName (), ce n'est pas du tout un problème. Pas de conflit. Ouais méthodes statiques!
SELF ::
Si vous codez en dehors de l'objet qui a la méthode statique à laquelle vous voulez vous référer, vous devez l'appeler en utilisant le nom de l'objet View :: format_phone_number ($ phone_number); Si vous codez à l' intérieur de l'objet qui a la méthode statique à laquelle vous voulez vous référer, vous pouvez soit utiliser le nom de l'objet View :: format_phone_number ($ pn), OU vous pouvez utiliser le raccourci self :: format_phone_number ($ pn)
Il en va de même pour les variables statiques:
Exemple: View :: templates_path versus self :: templates_path
Dans la classe DB, si nous faisions référence à une méthode statique d'un autre objet, nous utiliserions le nom de l'objet:
Exemple: Session :: getUsersOnline ();
Mais si la classe DB voulait faire référence à sa propre variable statique, elle dirait juste self:
Exemple: self :: connection;
Très bonne réponse. Je veux juste souligner que lorsque vous faites référence à un attribut statique, vous devez utiliser un $signe. Par exempleself::$templates_path
En PHP, vous utilisez le mot-clé self pour accéder aux propriétés et méthodes statiques.
Le problème est que vous pouvez remplacer $this->method()par self::method()n'importe où, quel que soit le cas method()est déclarée statique ou non. Alors, lequel devez-vous utiliser?
Considérez ce code:
classParentClass{function test(){self::who();// will output 'parent'
$this->who();// will output 'child'}function who(){
echo 'parent';}}classChildClassextendsParentClass{function who(){
echo 'child';}}
$obj =newChildClass();
$obj->test();
Dans cet exemple, self::who()affichera toujours «parent», tandis que $this->who()dépendra de la classe de l'objet.
Maintenant, nous pouvons voir que self fait référence à la classe dans laquelle il est appelé, tandis que se $thisréfère à la classe de l'objet courant .
Par conséquent, vous ne devez utiliser self que lorsqu'il $thisn'est pas disponible ou lorsque vous ne souhaitez pas autoriser les classes descendantes à remplacer la méthode actuelle.
Selon http://www.php.net/manual/en/language.oop5.static.php, il n'y en a pas $self. Il n'y a $this, pour faire référence à l'instance actuelle de la classe (l'objet), et self, qui peuvent être utilisés pour faire référence aux membres statiques d'une classe. La différence entre une instance d'objet et une classe entre en jeu ici.
Suggestion: lisez cette réponse lors d'un déclenchement avec de l'acide.
2015 à 10h08
16
Je crois que la question n'était pas de savoir si vous pouvez appeler le membre statique de la classe en appelant ClassName::staticMember. La question était quelle est la différence entre utiliser self::classmemberet $this->classmember.
Par exemple, les deux exemples suivants fonctionnent sans erreur, que vous utilisiez self::ou$this->
Il est particulièrement amusant que vous commenciez votre réponse par "Je pense que la question n'était pas de savoir si vous pouvez appeler le membre statique de la classe en appelant ClassName :: staticMember. La question était de savoir quelle était la différence entre l'utilisation de self :: classmember et $ this-> classmember" puis vous continuez à ne montrer aucune différence. En fait, vous montrez une instance où les deux options fonctionnent de manière identique. -1
Buttle Butkus
Néanmoins utile. La portée portait sur la résolution et cette partie n'est pas claire dans le manuel php. Je le trouve toujours utile
renoirb
2
Fatal error: Access to undeclared static property: Person::$name in D:\LAMP\www\test.php on line 16
K-Gun
16
self fait référence à la classe actuelle (dans laquelle elle est appelée),
$thisfait référence à l'objet actuel. Vous pouvez utiliser statique au lieu de self. Voir l'exemple:
Le pointeur d'objet $thisvers fait référence à l'objet actuel.
La valeur de classe staticfait référence à l'objet actuel.
La valeur de classe selffait référence à la classe exacte dans laquelle elle a été définie.
La valeur de classe parentfait référence au parent de la classe exacte dans laquelle elle a été définie.
Voir l'exemple suivant qui montre la surcharge.
<?php
class A {publicstaticfunction newStaticClass(){returnnewstatic;}publicstaticfunction newSelfClass(){returnnewself;}publicfunction newThisClass(){returnnew $this;}}class B extends A
{publicfunction newParentClass(){returnnew parent;}}
$b =new B;
var_dump($b::newStaticClass());// B
var_dump($b::newSelfClass());// A because self belongs to "A"
var_dump($b->newThisClass());// B
var_dump($b->newParentClass());// Aclass C extends B
{publicstaticfunction newSelfClass(){returnnewself;}}
$c =new C;
var_dump($c::newStaticClass());// C
var_dump($c::newSelfClass());// C because self now points to "C" class
var_dump($c->newThisClass());// C
var_dump($b->newParentClass());// A because parent was defined *way back* in class "B"
La plupart du temps, vous voulez vous référer à la classe actuelle, c'est pourquoi vous utilisez staticou $this. Cependant, il y a des moments où vous en avez besoinself parce que vous voulez la classe d'origine indépendamment de ce qui la prolonge. (Très, très rarement)
Ce sont les résultats pour 2 000 000 de runs, et voici le code que j'ai utilisé:
<?php
require'../vendor/autoload.php';// My small class to do benchmarks// All it does is looping over every test x times and record the// time it takes using `microtime(true)`// Then, the percentage is calculated, with 100% being the quickest// Times are being rouned for outputting only, not to calculate the percentages
$b =newTleb\Benchmark\Benchmark(2000000);classFoo{publicfunction calling_this(){
$this->called();}publicfunction calling_self(){self::called();}publicfunction calling_static(){static::called();}publicstaticfunction called(){}}
$b->add('$this->',function(){ $foo =newFoo; $foo->calling_this();});
$b->add('self::',function(){ $foo =newFoo; $foo->calling_self();});
$b->add('static::',function(){ $foo =newFoo; $foo->calling_static();});
$b->run();
L'appel de la fonction no-op 2 000 000 fois dure 1 seconde. Je dois aimer PHP.
rr-
Bon vieux PHP. :) Mais un appel = 0,001 ms. C'est si mauvais?
tleb
Je crois que cela (et des choses similaires) est la raison pour laquelle des choses telles que les ORM semblent lentes à moins que vous ne mettiez en cache des éléments, et les générateurs de sites statiques sont une chose.
rr
2
Il devrait théoriquement prendre 1 cycle d'horloge du processeur, ce qui fait environ 1 / 2e9 s = 0.5 nsces jours-ci
Buddy
Relisez ma réponse. Attention: cela crée aussi la classe . Je ne sais pas pourquoi je n'ai pas utilisé le usemot - clé tbh, mais je n'ai plus PHP pour refaire un benchmark, et je n'ai pas vraiment envie de le réinstaller.
tleb
13
Lorsqu'il selfest utilisé avec l' ::opérateur, il fait référence à la classe actuelle, ce qui peut être fait à la fois dans des contextes statiques et non statiques. $thisfait référence à l'objet lui-même. De plus, il est parfaitement légal d'utiliser $thispour appeler des méthodes statiques (mais pas pour faire référence à des champs).
Je suis tombé sur la même question et la réponse simple est:
$this nécessite une instance de la classe
self:: ne
Chaque fois que vous utilisez des méthodes statiques ou des attributs statiques et que vous souhaitez les appeler sans avoir un objet de la classe instancié, vous devez les utiliser self:pour les appeler, car $thisil faut toujours créer un objet.
$thisfait référence à l'objet de classe actuel, selffait référence à la classe actuelle (pas d'objet). La classe est le plan directeur de l'objet. Vous définissez donc une classe, mais vous construisez des objets.
En d'autres termes, utilisez self for staticet this for none-static members or methods.
également dans le scénario enfant / parent self / parentest principalement utilisé pour identifier les membres et les méthodes de la classe enfant et parent.
De plus, depuis $this::n'a pas encore été discuté.
À titre informatif uniquement, à partir de PHP 5.3 lorsque vous traitez avec des objets instanciés pour obtenir la valeur de portée actuelle, par opposition à l'utilisation static::, vous pouvez également l'utiliser $this::comme tel.
classFoo{const NAME ='Foo';//Always Foo::NAME (Foo) due to selfprotectedstatic $staticName =self::NAME;publicfunction __construct(){
echo $this::NAME;}publicfunction getStaticName(){
echo $this::$staticName;}}classBarextendsFoo{const NAME ='FooBar';/**
* override getStaticName to output Bar::NAME
*/publicfunction getStaticName(){
$this::$staticName = $this::NAME;
parent::getStaticName();}}
$foo =newFoo;//outputs Foo
$bar =newBar;//outputs FooBar
$foo->getStaticName();//outputs Foo
$bar->getStaticName();//outputs FooBar
$foo->getStaticName();//outputs FooBar
L'utilisation du code ci-dessus n'est pas une pratique courante ou recommandée, mais vise simplement à illustrer son utilisation et consiste à agir davantage comme un "Le saviez-vous?" en référence à la question de l'affiche originale.
Il représente également l'utilisation $object::CONSTANTpar exemple echo $foo::NAME;de$this::NAME;
À utiliser selfsi vous souhaitez appeler une méthode d'une classe sans créer d'objet / instance de cette classe, économisant ainsi de la RAM (utilisez parfois self à cet effet). En d'autres termes, il appelle en fait une méthode de manière statique. À utiliser thispour la perspective d'objet.
Selon php.net , il y a trois mots - clés spécifiques dans ce contexte: self, parentet static. Ils sont utilisés pour accéder aux propriétés ou méthodes de l'intérieur de la définition de classe.
$this, d'autre part, est utilisé pour appeler une instance et des méthodes de n'importe quelle classe tant que cette classe est accessible.
mot-clé self :: utilisé pour la classe actuelle et utilisé pour accéder aux membres statiques, aux méthodes et aux constantes. Mais dans le cas de $ this, vous ne pouvez pas appeler le membre statique, la méthode et les fonctions.
Vous pouvez utiliser le mot-clé self :: dans une autre classe et accéder aux membres statiques, à la méthode et aux constantes. Quand il sera étendu de la classe parente et même en cas de $ this mot - clé. Vous pouvez accéder aux membres non statiques, à la méthode et à la fonction dans une autre classe lorsqu'elle sera étendue à partir de la classe parente.
Le code donné ci-dessous est un exemple de self :: et $ this mot - clé. Copiez et collez simplement le code dans votre fichier de code et voyez le résultat.
class cars{var $doors=4;static $car_wheel=4;publicfunction car_features(){
echo $this->doors." Doors <br>";
echo self::$car_wheel." Wheels <br>";}}class spec extends cars{function car_spec(){print(self::$car_wheel." Doors <br>");print($this->doors." Wheels <br>");}}/********Parent class output*********/
$car =new cars;
print_r($car->car_features());
echo "------------------------<br>";/********Extend class from another class output**********/
$car_spec_show=new spec;print($car_spec_show->car_spec());
Réponses:
Réponse courte
Réponse complète
Voici un exemple d' utilisation correcte de
$this
etself
pour les variables membres non statiques et statiques:Voici un exemple d' utilisation incorrecte de
$this
etself
pour les variables membres non statiques et statiques:Voici un exemple de polymorphisme avec
$this
pour les fonctions membres:Voici un exemple de suppression du comportement polymorphe à l'aide
self
de fonctions membres:Depuis http://www.phpbuilder.com/board/showthread.php?t=10354489 :
Par http://board.phpbuilder.com/member.php?145249-laserlight
la source
self
est utilisé avec l'opérateur de résolution de portée::
pour faire référence à la classe actuelle; cela peut être fait à la fois dans des contextes statiques et non statiques. De plus, il est parfaitement légal d'utiliser$this
pour appeler des méthodes statiques (mais pas pour référencer des champs).$this::
?Le mot-clé self ne fait PAS simplement référence à la «classe actuelle», du moins pas d'une manière qui vous limite aux membres statiques. Dans le contexte d'un membre non statique,
self
fournit également un moyen de contourner la vtable ( voir wiki sur vtable ) pour l'objet actuel. Tout comme vous pouvez utiliserparent::methodName()
pour appeler la version parent d'une fonction, vous pouvez également appelerself::methodName()
pour appeler l'implémentation de classes actuelle d'une méthode.Cela produira:
sayHello()
utilise le$this
pointeur, donc la vtable est invoquée pour appelerGeek::getTitle()
.sayGoodbye()
utiliseself::getTitle()
, donc la vtable n'est pas utilisée etPerson::getTitle()
est appelée. Dans les deux cas, nous avons affaire à la méthode d'un objet instancié, et avons accès au$this
pointeur dans les fonctions appelées.la source
self
se trouve" / "la définition de classe, elle fait littéralement partie de" ainsi que "la classe de l'objet" (qui serait en faitstatic
).$this::
?$this::
; tous les cas possibles sont déjà couverts par des syntaxes plus couramment utilisées. Selon ce que vous voulez dire, l' utilisation$this->
,self::
oustatic::
.NE PAS UTILISER
self::
, utiliserstatic::
Il y a un autre aspect de self :: qui mérite d'être mentionné. Désagréablement
self::
fait référence à la portée au point de définition et non au point d'exécution . Considérez cette classe simple avec deux méthodes:Si nous appelons,
Person::status()
nous verrons "La personne est vivante". Considérez maintenant ce qui se passe lorsque nous créons une classe qui hérite de ceci:En appelant,
Deceased::status()
nous nous attendrions à voir «La personne est décédée», mais ce que nous voyons est «La personne est vivante», car la portée contient la définition de la méthode d'origine lorsque l'appel à aself::getStatus()
été défini.PHP 5.3 a une solution. L'
static::
opérateur de résolution implémente la "liaison statique tardive", ce qui est une façon élégante de dire qu'elle est liée à la portée de la classe appelée. Modifiez la lignestatus()
pourstatic::getStatus()
et les résultats sont ce que vous attendez. Dans les anciennes versions de PHP, vous devrez trouver un kludge pour ce faire.Voir la documentation PHP
Donc, pour répondre à la question pas comme demandé ...
$this->
fait référence à l'objet courant (une instance d'une classe), tandis questatic::
fait référence à une classela source
getStatus
méthode comme celle que j'appellerais pour une instance de classe, pas pour une classe.self::
, vous pouvez l'obtenir, moins prêter à confusion, en utilisant le nom de classe spécifique, par exempleMyClass::
.Pour vraiment comprendre de quoi nous parlons lorsque nous parlons de
self
versus$this
, nous devons réellement creuser ce qui se passe au niveau conceptuel et pratique. Je ne pense pas que l'une des réponses le fasse correctement, alors voici ma tentative.Commençons par parler de ce qu'est une classe et un objet .
Classes et objets, conceptuellement
Alors, qu'est - ce qu'une classe ? Beaucoup de gens le définissent comme un plan directeur ou un modèle pour un objet. En fait, vous pouvez en savoir plus sur les classes en PHP ici . Et dans une certaine mesure, c'est ce que c'est vraiment. Regardons une classe:
Comme vous pouvez le constater, il y a une propriété sur cette classe appelée
$name
et une méthode (fonction) appeléesayHello()
.Il est très important de noter que la classe est une structure statique. Ce qui signifie que la classe
Person
, une fois définie, est toujours la même partout où vous la regardez.Un objet d'autre part est ce qu'on appelle une instance d'une classe. Cela signifie que nous prenons le «plan directeur» de la classe et que nous l'utilisons pour faire une copie dynamique. Cette copie est désormais spécifiquement liée à la variable dans laquelle elle est stockée. Par conséquent, toute modification apportée à une instance est locale à cette instance.
Nous créons de nouvelles instances d'une classe en utilisant l'
new
opérateur.Par conséquent, nous disons qu'une classe est une structure globale et un objet est une structure locale. Ne vous inquiétez pas de cette drôle de
->
syntaxe, nous allons y revenir un peu.Une autre chose dont nous devrions parler, c'est que nous pouvons vérifier si une instance est une
instanceof
classe particulière:$bob instanceof Person
qui retourne un booléen si l'$bob
instance a été créée en utilisant laPerson
classe, ou un enfant dePerson
.Définition de l'État
Examinons donc un peu ce que contient réellement une classe. Il y a 5 types de "choses" qu'une classe contient:
Propriétés - Considérez-les comme des variables que chaque instance contiendra.
Propriétés statiques - Considérez-les comme des variables partagées au niveau de la classe. Cela signifie qu'ils ne sont jamais copiés par chaque instance.
Méthodes - Ce sont des fonctions que chaque instance contiendra (et fonctionnera sur les instances).
Méthodes statiques - Ce sont des fonctions qui sont partagées dans toute la classe. Ils ne fonctionnent pas sur les instances, mais uniquement sur les propriétés statiques.
Constantes - Constantes résolues par classe. Ne pas aller plus loin ici, mais en ajoutant pour être complet:
Donc, fondamentalement, nous stockons des informations sur la classe et le conteneur d'objets en utilisant des "astuces" sur l' électricité statique qui identifient si les informations sont partagées (et donc statiques) ou non (et donc dynamiques).
État et méthodes
A l'intérieur d'une méthode, l'instance d'un objet est représentée par la
$this
variable. L'état actuel de cet objet est là, et la mutation (modification) de toute propriété entraînera une modification de cette instance (mais pas des autres).Si une méthode est appelée statiquement, la
$this
variable n'est pas définie . En effet, aucune instance n'est associée à un appel statique.La chose intéressante ici est de savoir comment les appels statiques sont effectués. Parlons donc de la façon dont nous accédons à l'État:
État d'accès
Alors maintenant que nous avons enregistré cet état, nous devons y accéder. Cela peut devenir un peu délicat (ou bien plus qu'un peu), alors divisons cela en deux points de vue: de l'extérieur d'une instance / classe (disons à partir d'un appel de fonction normal ou de la portée globale) et à l'intérieur d'une instance / classe (à partir d'une méthode sur l'objet).
De l'extérieur d'une instance / classe
De l'extérieur d'une instance / classe, nos règles sont assez simples et prévisibles. Nous avons deux opérateurs, et chacun nous dit immédiatement si nous avons affaire à une instance ou à une classe statique:
->
- objet-opérateur - Ceci est toujours utilisé lorsque nous accédons à une instance.Il est important de noter que l'appel
Person->foo
n'a pas de sens (puisqu'ilPerson
s'agit d'une classe et non d'une instance). Par conséquent, c'est une erreur d'analyse.::
- scope-resolution-operator - Ceci est toujours utilisé pour accéder à une propriété ou une méthode statique de classe.De plus, nous pouvons appeler une méthode statique sur un objet de la même manière:
Il est extrêmement important de noter que lorsque nous faisons cela de l'extérieur , l'instance de l'objet est masquée de la
bar()
méthode. Cela signifie que c'est exactement la même chose que la course:Par conséquent,
$this
n'est pas défini dans l'appel statique.De l'intérieur d'une instance / classe
Les choses changent un peu ici. Les mêmes opérateurs sont utilisés, mais leur signification devient nettement floue.
L' opérateur d'objet
->
est toujours utilisé pour effectuer des appels à l'état d'instance de l'objet.L'appel de la
bar()
méthode sur$foo
(une instance deFoo
) à l'aide de l'opérateur objet:$foo->bar()
entraînera la version de l'instance de$a
.Voilà donc ce que nous attendons.
La signification de l'
::
opérateur change cependant. Cela dépend du contexte de l'appel à la fonction courante:Dans un contexte statique
Dans un contexte statique, tous les appels effectués à l'aide de
::
seront également statiques. Regardons un exemple:L'appel
Foo::bar()
appellera labaz()
méthode de manière statique et ne$this
sera donc pas rempli. Il convient de noter que dans les versions récentes de PHP (5.3+), cela déclenchera uneE_STRICT
erreur, car nous appelons des méthodes non statiques de manière statique.Dans un contexte d'instance
Dans un contexte d'instance, en revanche, les appels effectués à l'aide de
::
dépendent du destinataire de l'appel (la méthode que nous appelons). Si la méthode est définie commestatic
, alors elle utilisera un appel statique. Si ce n'est pas le cas, il transmettra les informations d'instance.Ainsi, en regardant le code ci-dessus, l'appel
$foo->bar()
reviendratrue
, car l'appel "statique" se produit à l'intérieur d'un contexte d'instance.Ça a du sens? Je ne le pensais pas. C'est confu.
Mots-clés raccourcis
Parce que tout lier ensemble en utilisant des noms de classe est plutôt sale, PHP fournit 3 mots-clés de "raccourci" de base pour faciliter la résolution de la portée.
self
- Cela fait référence au nom de classe actuel. C'estself::baz()
la même chose queFoo::baz()
dans laFoo
classe (n'importe quelle méthode).parent
- Cela fait référence au parent de la classe actuelle.static
- Il s'agit de la classe appelée. Grâce à l'héritage, les classes enfants peuvent remplacer les méthodes et les propriétés statiques. Ainsi, les appeler à l'aidestatic
d'un nom de classe nous permet de déterminer d'où vient l'appel, plutôt que le niveau actuel.Exemples
La façon la plus simple de comprendre cela est de commencer à regarder quelques exemples. Choisissons une classe:
Maintenant, nous examinons également l'héritage ici. Ignorez un instant qu'il s'agit d'un mauvais modèle d'objet, mais regardons ce qui se passe lorsque nous jouons avec ceci:
Ainsi, le compteur d'ID est partagé entre les deux instances et les enfants (parce que nous l'utilisons
self
pour y accéder. Si nous l'utilisionsstatic
, nous pourrions le remplacer dans une classe enfant).Notez que nous exécutons la méthode d'
Person::getName()
instance à chaque fois. Mais nous utilisons leparent::getName()
pour le faire dans l'un des cas (le cas des enfants). C'est ce qui rend cette approche puissante.Mot de prudence # 1
Notez que le contexte d'appel est ce qui détermine si une instance est utilisée. Donc:
N'est pas toujours vrai.
Maintenant, c'est vraiment bizarre ici. Nous appelons une classe différente, mais celle
$this
qui est transmise à laFoo::isFoo()
méthode est l'instance de$bar
.Cela peut provoquer toutes sortes de bugs et WTF-ery conceptuel. Donc , je suggère fortement d' éviter l'
::
opérateur à partir de méthodes d'instance sur quoi que ce soit , sauf ces trois mots - clés « raccourci » virtuels (static
,self
etparent
).Mot de prudence # 2
Notez que les méthodes et propriétés statiques sont partagées par tous. Cela en fait essentiellement des variables globales. Avec tous les mêmes problèmes que les globaux. Donc, j'hésiterais vraiment à stocker des informations dans des méthodes / propriétés statiques à moins que vous ne soyez à l'aise avec le fait qu'elles soient vraiment globales.
Mot de prudence # 3
En général, vous voudrez utiliser ce que l'on appelle la liaison statique tardive en utilisant
static
au lieu deself
. Mais notez que ce n'est pas la même chose, donc dire "toujours utiliser à lastatic
place deself
est vraiment à courte vue. Au lieu de cela, arrêtez-vous et pensez à l'appel que vous voulez faire et pensez si vous voulez que les classes enfants soient capables de remplacer cette résolution statique appel.TL / DR
Dommage, revenez en arrière et lisez-le. C'est peut-être trop long, mais c'est aussi long car c'est un sujet complexe
TL / DR # 2
OK bien. En bref,
self
est utilisé pour référencer le nom de la classe actuelle dans une classe, où as$this
fait référence à l' instance d' objet actuelle . Notez qu'ilself
s'agit d'un raccourci copier / coller. Vous pouvez le remplacer en toute sécurité par le nom de votre classe, et cela fonctionnera bien. Mais$this
c'est une variable dynamique qui ne peut pas être déterminée à l'avance (et peut-être même pas votre classe).TL / DR # 3
Si l'opérateur objet est utilisé (
->
), alors vous savez toujours que vous avez affaire à une instance. Si l'opérateur scope-resolution-operator est utilisé (::
), vous avez besoin de plus d'informations sur le contexte (sommes-nous déjà dans un contexte d'objet? Sommes-nous en dehors d'un objet? Etc).la source
$this
ne sera pas défini si vous suivez les "normes strictes" et n'appelez pas de méthodes statiques qui ne sont pas définies comme statiques. Je vois le résultat que vous avez expliqué ici: 3v4l.org/WeHVM D'accord, vraiment bizarre.Foo::isFoo()
on l'appelle statiquement,$this
ne sera pas défini. C'est un comportement plus intuitif à mon avis. - Un autre résultat différent est donné s'ilBar
devait s'étendre deFoo
. Ensuite, l'appelFoo::isFoo()
serait en fait dans le contexte de l'instance (non spécifique à PHP7).self
(pas $ self) fait référence au type de classe, où as$this
fait référence à l' instance actuelle de la classe.self
est à utiliser dans les fonctions membres statiques pour vous permettre d'accéder aux variables membres statiques.$this
est utilisé dans les fonctions membres non statiques et est une référence à l'instance de la classe sur laquelle la fonction membre a été appelée.Parce que
this
c'est un objet, vous l'utilisez comme:$this->member
Parce que ce
self
n'est pas un objet, c'est fondamentalement un type qui fait automatiquement référence à la classe actuelle, vous l'utilisez comme:self::member
la source
$this->
est utilisé pour faire référence à une instance spécifique des variables d'une classe (variables membres) ou des méthodes.$ derek est maintenant une instance spécifique de Person. Chaque personne a un prénom et un nom de famille, mais $ derek a un prénom et un nom de famille spécifiques (Derek Martin). Dans l'instance $ derek, nous pouvons les désigner comme $ this-> first_name et $ this-> last_name
ClassName :: est utilisé pour faire référence à ce type de classe, et à ses variables statiques, aux méthodes statiques. Si cela peut vous aider, vous pouvez mentalement remplacer le mot "statique" par "partagé". Parce qu'ils sont partagés, ils ne peuvent pas faire référence à $ this, qui fait référence à une instance spécifique (non partagée). Les variables statiques (ie statique $ db_connection) peuvent être partagées entre toutes les instances d'un type d'objet. Par exemple, tous les objets de base de données partagent une seule connexion (connexion $ statique).
Variables statiques Exemple: Imaginez que nous avons une classe de base de données avec une seule variable membre: static $ num_connections; Maintenant, mettez ceci dans le constructeur:
Tout comme les objets ont des constructeurs, ils ont aussi des destructeurs, qui sont exécutés lorsque l'objet meurt ou n'est pas défini:
Chaque fois que nous créons une nouvelle instance, cela augmentera notre compteur de connexions d'une unité. Chaque fois que nous détruisons ou cessons d'utiliser une instance, cela diminue le compteur de connexions d'une unité. De cette façon, nous pouvons surveiller le nombre d'instances de l'objet de base de données que nous utilisons avec:
Parce que $ num_connections est statique (partagé), il reflétera le nombre total d'objets de base de données actifs. Vous avez peut-être vu cette technique utilisée pour partager des connexions de base de données entre toutes les instances d'une classe de base de données. Cela est dû au fait que la création de la connexion à la base de données prend beaucoup de temps, il est donc préférable d'en créer une seule et de la partager (c'est ce qu'on appelle un modèle Singleton).
Les méthodes statiques (c'est-à-dire View :: format_phone_number ($ digits) statiques publiques) peuvent être utilisées SANS d'abord instancier l'un de ces objets (c'est-à-dire qu'elles ne se réfèrent pas en interne à $ this).
Exemple de méthode statique:
Comme vous pouvez le voir, la fonction statique publique prettyName ne sait rien de l'objet. Cela fonctionne simplement avec les paramètres que vous transmettez, comme une fonction normale qui ne fait pas partie d'un objet. Pourquoi s'embêter, alors, si nous pouvions simplement ne pas l'avoir comme partie de l'objet?
SELF :: Si vous codez en dehors de l'objet qui a la méthode statique à laquelle vous voulez vous référer, vous devez l'appeler en utilisant le nom de l'objet View :: format_phone_number ($ phone_number); Si vous codez à l' intérieur de l'objet qui a la méthode statique à laquelle vous voulez vous référer, vous pouvez soit utiliser le nom de l'objet View :: format_phone_number ($ pn), OU vous pouvez utiliser le raccourci self :: format_phone_number ($ pn)
Il en va de même pour les variables statiques: Exemple: View :: templates_path versus self :: templates_path
Dans la classe DB, si nous faisions référence à une méthode statique d'un autre objet, nous utiliserions le nom de l'objet: Exemple: Session :: getUsersOnline ();
Mais si la classe DB voulait faire référence à sa propre variable statique, elle dirait juste self: Exemple: self :: connection;
J'espère que cela aide à clarifier les choses :)
la source
$
signe. Par exempleself::$templates_path
De ce billet de blog :
la source
En PHP, vous utilisez le mot-clé self pour accéder aux propriétés et méthodes statiques.
Le problème est que vous pouvez remplacer
$this->method()
parself::method()
n'importe où, quel que soit le casmethod()
est déclarée statique ou non. Alors, lequel devez-vous utiliser?Considérez ce code:
Dans cet exemple,
self::who()
affichera toujours «parent», tandis que$this->who()
dépendra de la classe de l'objet.Maintenant, nous pouvons voir que self fait référence à la classe dans laquelle il est appelé, tandis que se
$this
réfère à la classe de l'objet courant .Par conséquent, vous ne devez utiliser self que lorsqu'il
$this
n'est pas disponible ou lorsque vous ne souhaitez pas autoriser les classes descendantes à remplacer la méthode actuelle.la source
Dans une définition de classe,
$this
fait référence à l'objet actuel, tandis queself
fait référence à la classe actuelle.Il est nécessaire de faire référence à un élément de classe en utilisant
self
et de faire référence à un élément d'objet en utilisant$this
.la source
la source
Selon http://www.php.net/manual/en/language.oop5.static.php, il n'y en a pas
$self
. Il n'y a$this
, pour faire référence à l'instance actuelle de la classe (l'objet), et self, qui peuvent être utilisés pour faire référence aux membres statiques d'une classe. La différence entre une instance d'objet et une classe entre en jeu ici.la source
Je crois que la question n'était pas de savoir si vous pouvez appeler le membre statique de la classe en appelant
ClassName::staticMember
. La question était quelle est la différence entre utiliserself::classmember
et$this->classmember
.Par exemple, les deux exemples suivants fonctionnent sans erreur, que vous utilisiez
self::
ou$this->
la source
Fatal error: Access to undeclared static property: Person::$name in D:\LAMP\www\test.php on line 16
self
fait référence à la classe actuelle (dans laquelle elle est appelée),$this
fait référence à l'objet actuel. Vous pouvez utiliser statique au lieu de self. Voir l'exemple:Sortie: parent enfant
la source
$this
vers fait référence à l'objet actuel.static
fait référence à l'objet actuel.self
fait référence à la classe exacte dans laquelle elle a été définie.parent
fait référence au parent de la classe exacte dans laquelle elle a été définie.Voir l'exemple suivant qui montre la surcharge.
La plupart du temps, vous voulez vous référer à la classe actuelle, c'est pourquoi vous utilisez
static
ou$this
. Cependant, il y a des moments où vous en avez besoinself
parce que vous voulez la classe d'origine indépendamment de ce qui la prolonge. (Très, très rarement)la source
Comme personne ici n'a parlé de performances, voici un petit benchmark que j'ai fait (5.6):
Ce sont les résultats pour 2 000 000 de runs, et voici le code que j'ai utilisé:
la source
1 / 2e9 s = 0.5 ns
ces jours-ciuse
mot - clé tbh, mais je n'ai plus PHP pour refaire un benchmark, et je n'ai pas vraiment envie de le réinstaller.Lorsqu'il
self
est utilisé avec l'::
opérateur, il fait référence à la classe actuelle, ce qui peut être fait à la fois dans des contextes statiques et non statiques.$this
fait référence à l'objet lui-même. De plus, il est parfaitement légal d'utiliser$this
pour appeler des méthodes statiques (mais pas pour faire référence à des champs).la source
Je suis tombé sur la même question et la réponse simple est:
$this
nécessite une instance de la classeself::
neChaque fois que vous utilisez des méthodes statiques ou des attributs statiques et que vous souhaitez les appeler sans avoir un objet de la classe instancié, vous devez les utiliser
self:
pour les appeler, car$this
il faut toujours créer un objet.la source
$this
fait référence à l'objet de classe actuel,self
fait référence à la classe actuelle (pas d'objet). La classe est le plan directeur de l'objet. Vous définissez donc une classe, mais vous construisez des objets.En d'autres termes, utilisez
self for static
etthis for none-static members or methods
.également dans le scénario enfant / parent
self / parent
est principalement utilisé pour identifier les membres et les méthodes de la classe enfant et parent.la source
De plus, depuis
$this::
n'a pas encore été discuté.À titre informatif uniquement, à partir de PHP 5.3 lorsque vous traitez avec des objets instanciés pour obtenir la valeur de portée actuelle, par opposition à l'utilisation
static::
, vous pouvez également l'utiliser$this::
comme tel.http://ideone.com/7etRHy
L'utilisation du code ci-dessus n'est pas une pratique courante ou recommandée, mais vise simplement à illustrer son utilisation et consiste à agir davantage comme un "Le saviez-vous?" en référence à la question de l'affiche originale.
Il représente également l'utilisation
$object::CONSTANT
par exempleecho $foo::NAME;
de$this::NAME;
la source
À utiliser
self
si vous souhaitez appeler une méthode d'une classe sans créer d'objet / instance de cette classe, économisant ainsi de la RAM (utilisez parfois self à cet effet). En d'autres termes, il appelle en fait une méthode de manière statique. À utiliserthis
pour la perspective d'objet.la source
Cas 1: l'utilisation
self
peut être utilisée pour les constantes de classeSi vous voulez l'appeler en dehors de la classe, utilisez
classA::POUNDS_TO_KILOGRAMS
pour accéder aux constantesCas 2: pour les propriétés statiques
la source
Selon php.net , il y a trois mots - clés spécifiques dans ce contexte:
self
,parent
etstatic
. Ils sont utilisés pour accéder aux propriétés ou méthodes de l'intérieur de la définition de classe.$this
, d'autre part, est utilisé pour appeler une instance et des méthodes de n'importe quelle classe tant que cette classe est accessible.la source
mot-clé self :: utilisé pour la classe actuelle et utilisé pour accéder aux membres statiques, aux méthodes et aux constantes. Mais dans le cas de $ this, vous ne pouvez pas appeler le membre statique, la méthode et les fonctions.
Vous pouvez utiliser le mot-clé self :: dans une autre classe et accéder aux membres statiques, à la méthode et aux constantes. Quand il sera étendu de la classe parente et même en cas de $ this mot - clé. Vous pouvez accéder aux membres non statiques, à la méthode et à la fonction dans une autre classe lorsqu'elle sera étendue à partir de la classe parente.
Le code donné ci-dessous est un exemple de self :: et $ this mot - clé. Copiez et collez simplement le code dans votre fichier de code et voyez le résultat.
la source