Nur ein FYI, Ihr erstes Beispiel ist eine Instanzvariable, die eine statische Methode aufruft, was nicht möglich ist, da eine statische Methode Teil der Klasse ist und über eine Instanzvariable nicht zugänglich ist.
Joejoeson
Sie können das $ this jetzt löschen. Bitte funktioniert es nicht, wenn nur statische Methoden verwendet werden und keine Instanz vorhanden ist.
...aber wieso? $ this-> staticMethod () funktioniert auch. Können Sie erklären, warum self :: staticMethod () korrekter ist (wenn ja)?
Ian Dunn
29
@ Ian Dunn Einfach ausgedrückt, $thisexistiert nur, wenn ein Objekt instanziiert wurde und Sie es nur $this->methodinnerhalb eines vorhandenen Objekts verwenden können. Wenn Sie kein Objekt haben, sondern nur eine statische Methode aufrufen und in dieser Methode eine andere statische Methode in derselben Klasse aufrufen möchten, müssen Sie diese verwenden self::. Um mögliche Fehler (und strenge Warnungen) zu vermeiden, ist es besser, diese zu verwenden self.
Jeroen
1
Vielen Dank! In Laravel stellte ich fest, dass ich versehentlich die statische Methode über einen erweiterten Controller mit $thisaufrief, aber das Problem trat erst auf, als Code an gesendet wurde stage. Es kamen keine Fehler zurück, der Wert war gerecht 0. self::
foo()Schauen wir uns innerhalb der Methode die verschiedenen Optionen an:
$this->staticMethod();
Das ruft also staticMethod()als Instanzmethode auf, oder? Es tut nicht. Dies liegt daran, dass die Methode deklariert ist, da public staticder Interpreter sie als statische Methode aufruft, sodass sie wie erwartet funktioniert. Es könnte argumentiert werden, dass dies aus dem Code weniger offensichtlich macht, dass ein statischer Methodenaufruf stattfindet.
$this::staticMethod();
Seit PHP 5.3 können Sie $var::method()damit meinen <class-of-$var>::; Dies ist sehr praktisch, obwohl der obige Anwendungsfall immer noch ziemlich unkonventionell ist. Das bringt uns zu der gebräuchlichsten Art, eine statische Methode aufzurufen:
self::staticMethod();
Nun, bevor Sie anfangen zu denken , dass das ::ist der statische Call - Betreiber, lassen Sie mich Ihnen ein anderes Beispiel:
self::bar();
Dies wird gedruckt baz = 1, was bedeutet, dass $this->bar()und self::bar()genau das gleiche tun; Das liegt daran, dass ::es sich nur um einen Bereichsauflösungsoperator handelt. Es ist dort zu machen parent::, self::und static::Arbeit und geben Sie auf statische Variablen zugreifen; Wie eine Methode aufgerufen wird, hängt von ihrer Signatur ab und davon, wie der Aufrufer aufgerufen wurde.
self::bar()scheint irreführend - ist das jetzt veraltet? (Verwenden self::zum Aufrufen einer Instanzmethode anstelle einer statischen Methode).
ToolmakerSteve
@ToolmakerSteve Inwiefern würdest du sagen, dass es irreführend ist?
Ja͢ck
Logischerweise gibt es selfbeim Aufrufen einer statischen Methode keine . Per Definition: Die statische Methode kann von überall aufgerufen werden und erhält keinen "self" -Parameter. Trotzdem sehe ich die Bequemlichkeit dieser phpSyntax, so dass Sie nicht schreiben müssen MyClassName::. Ich bin an statisch typisierte Sprachen gewöhnt, bei denen dem Compiler alle im aktuellen Bereich verfügbaren Variablen zugewiesen werden müssen, damit (das Äquivalent von) self::weggelassen werden kann. Also sagte man nur self instanceMethod; kein Grund zu sagen self staticMethod.
ToolmakerSteve
15
Dies ist eine sehr späte Antwort, fügt jedoch einige Details zu den vorherigen Antworten hinzu
Wenn statische Methoden in PHP von einer anderen statischen Methode in derselben Klasse aufgerufen werden sollen, ist es wichtig, zwischen selfund dem Klassennamen zu unterscheiden .
Dies liegt daran, dass es selfsich auf die Klasse bezieht, in der sich der Code befindet, und nicht auf die Klasse des Codes, von dem aus er aufgerufen wird.
Wenn Sie eine Methode verwenden möchten, die für eine Klasse definiert ist, die die ursprüngliche Klasse erbt, müssen Sie Folgendes verwenden:
Ich fand das informativ. Eine kleine Kleinigkeit, ich würde nicht sagen, dass die anderen Antworten "irreführend" sind. Genauer gesagt, dass sie "unvollständig" sind; Sie befassen sich nicht mit der (nicht gestellten) Frage, was self::in dem (seltenen) Fall geschieht, in dem eine statische Methode A eine andere statische Methode B aufruft und B in einer Unterklasse überschrieben wurde. IMHO ist es weniger verwirrend, das Überschreiben von Methoden auf "Instanz" -Methoden zu beschränken. Setzen Sie diese Fähigkeit auf statischer Ebene sparsam ein. Anders ausgedrückt, Leser Ihres Codes erwarten, dass die Methode die Instanzmethoden überschreibt (das ist die Essenz der OO-Codierung), nicht jedoch die statischen.
ToolmakerSteve
1
Sehr hilfreich und es macht Sinn, dass eine Erweiterung der Klasse nicht die ursprüngliche Klasse ist. Daher liegt es nahe, dass selfdies in diesem Fall nicht verwendet wird. Sie haben eine separate Klasse als Erweiterung der ersten Klasse deklariert. Die Verwendung selfinnerhalb der erweiterten Klasse würde sich auf die erweiterte Klasse beziehen. Dies widerspricht nicht den anderen Antworten, hilft aber sicherlich dabei, den Umfang von zu demonstrieren self.
Iyrin
2
In der späteren PHP-Version wird self::staticMethod();auch nicht funktionieren. Es wird der strenge Standardfehler ausgelöst.
In diesem Fall können wir ein Objekt derselben Klasse erstellen und nach Objekt aufrufen
Sie könnten dies tun, aber wenn fun1es nicht verwendet wird self, ist es nicht logisch, es zu einer Instanzmethode zu machen. Der richtige Weg, dies in PHP zu tun, besteht darin, zu deklarieren public static function fun1und dann durch Angabe der Klasse aufzurufen : Foo::fun1. Ich bin sicher, dass dies der beabsichtigte Weg ist, um diesen strengen Standardfehler zu beheben.
self
vs.$this
): stackoverflow.com/questions/151969/php-self-vs-thisAntworten:
Weitere Informationen zum Schlüsselwort Static.
quelle
$this
existiert nur, wenn ein Objekt instanziiert wurde und Sie es nur$this->method
innerhalb eines vorhandenen Objekts verwenden können. Wenn Sie kein Objekt haben, sondern nur eine statische Methode aufrufen und in dieser Methode eine andere statische Methode in derselben Klasse aufrufen möchten, müssen Sie diese verwendenself::
. Um mögliche Fehler (und strenge Warnungen) zu vermeiden, ist es besser, diese zu verwendenself
.$this
aufrief, aber das Problem trat erst auf, als Code an gesendet wurdestage
. Es kamen keine Fehler zurück, der Wert war gerecht0
.self::
Nehmen wir an, dies ist Ihre Klasse:
foo()
Schauen wir uns innerhalb der Methode die verschiedenen Optionen an:Das ruft also
staticMethod()
als Instanzmethode auf, oder? Es tut nicht. Dies liegt daran, dass die Methode deklariert ist, dapublic static
der Interpreter sie als statische Methode aufruft, sodass sie wie erwartet funktioniert. Es könnte argumentiert werden, dass dies aus dem Code weniger offensichtlich macht, dass ein statischer Methodenaufruf stattfindet.Seit PHP 5.3 können Sie
$var::method()
damit meinen<class-of-$var>::
; Dies ist sehr praktisch, obwohl der obige Anwendungsfall immer noch ziemlich unkonventionell ist. Das bringt uns zu der gebräuchlichsten Art, eine statische Methode aufzurufen:Nun, bevor Sie anfangen zu denken , dass das
::
ist der statische Call - Betreiber, lassen Sie mich Ihnen ein anderes Beispiel:Dies wird gedruckt
baz = 1
, was bedeutet, dass$this->bar()
undself::bar()
genau das gleiche tun; Das liegt daran, dass::
es sich nur um einen Bereichsauflösungsoperator handelt. Es ist dort zu machenparent::
,self::
undstatic::
Arbeit und geben Sie auf statische Variablen zugreifen; Wie eine Methode aufgerufen wird, hängt von ihrer Signatur ab und davon, wie der Aufrufer aufgerufen wurde.Um all dies in Aktion zu sehen, sehen Sie sich diese 3v4l.org-Ausgabe an .
quelle
self::bar()
scheint irreführend - ist das jetzt veraltet? (Verwendenself::
zum Aufrufen einer Instanzmethode anstelle einer statischen Methode).self
beim Aufrufen einer statischen Methode keine . Per Definition: Die statische Methode kann von überall aufgerufen werden und erhält keinen "self" -Parameter. Trotzdem sehe ich die Bequemlichkeit dieserphp
Syntax, so dass Sie nicht schreiben müssenMyClassName::
. Ich bin an statisch typisierte Sprachen gewöhnt, bei denen dem Compiler alle im aktuellen Bereich verfügbaren Variablen zugewiesen werden müssen, damit (das Äquivalent von)self::
weggelassen werden kann. Also sagte man nurself instanceMethod
; kein Grund zu sagenself staticMethod
.Dies ist eine sehr späte Antwort, fügt jedoch einige Details zu den vorherigen Antworten hinzu
Wenn statische Methoden in PHP von einer anderen statischen Methode in derselben Klasse aufgerufen werden sollen, ist es wichtig, zwischen
self
und dem Klassennamen zu unterscheiden .Nehmen Sie zum Beispiel diesen Code:
Die Ausgabe dieses Codes lautet:
Dies liegt daran, dass es
self
sich auf die Klasse bezieht, in der sich der Code befindet, und nicht auf die Klasse des Codes, von dem aus er aufgerufen wird.Wenn Sie eine Methode verwenden möchten, die für eine Klasse definiert ist, die die ursprüngliche Klasse erbt, müssen Sie Folgendes verwenden:
quelle
self::
in dem (seltenen) Fall geschieht, in dem eine statische Methode A eine andere statische Methode B aufruft und B in einer Unterklasse überschrieben wurde. IMHO ist es weniger verwirrend, das Überschreiben von Methoden auf "Instanz" -Methoden zu beschränken. Setzen Sie diese Fähigkeit auf statischer Ebene sparsam ein. Anders ausgedrückt, Leser Ihres Codes erwarten, dass die Methode die Instanzmethoden überschreibt (das ist die Essenz der OO-Codierung), nicht jedoch die statischen.self
dies in diesem Fall nicht verwendet wird. Sie haben eine separate Klasse als Erweiterung der ersten Klasse deklariert. Die Verwendungself
innerhalb der erweiterten Klasse würde sich auf die erweiterte Klasse beziehen. Dies widerspricht nicht den anderen Antworten, hilft aber sicherlich dabei, den Umfang von zu demonstrierenself
.In der späteren PHP-Version wird
self::staticMethod();
auch nicht funktionieren. Es wird der strenge Standardfehler ausgelöst.In diesem Fall können wir ein Objekt derselben Klasse erstellen und nach Objekt aufrufen
Hier ist das Beispiel
quelle
fun1
es nicht verwendet wirdself
, ist es nicht logisch, es zu einer Instanzmethode zu machen. Der richtige Weg, dies in PHP zu tun, besteht darin, zu deklarierenpublic static function fun1
und dann durch Angabe der Klasse aufzurufen :Foo::fun1
. Ich bin sicher, dass dies der beabsichtigte Weg ist, um diesen strengen Standardfehler zu beheben.