Was ist in PHP 5 der Unterschied zwischen self
und$this
?
Wann ist jeder angemessen?
Was ist in PHP 5 der Unterschied zwischen self
und$this
?
Wann ist jeder angemessen?
Antworten:
Verwenden Sie
$this
diese Option , um auf das aktuelle Objekt zu verweisen. Verwenden Sieself
diese Option , um auf die aktuelle Klasse zu verweisen. Mit anderen Worten,$this->member
für nicht statische Elemente verwenden,self::$member
für statische Elemente verwenden.
Hier ist ein Beispiel für die korrekte Verwendung von $this
und self
für nicht statische und statische Elementvariablen:
<?php
class X {
private $non_static_member = 1;
private static $static_member = 2;
function __construct() {
echo $this->non_static_member . ' '
. self::$static_member;
}
}
new X();
?>
Hier ist ein Beispiel für die falsche Verwendung von $this
und self
für nicht statische und statische Elementvariablen:
<?php
class X {
private $non_static_member = 1;
private static $static_member = 2;
function __construct() {
echo self::$non_static_member . ' '
. $this->static_member;
}
}
new X();
?>
Hier ist ein Beispiel für Polymorphismus mit $this
für Elementfunktionen:
<?php
class X {
function foo() {
echo 'X::foo()';
}
function bar() {
$this->foo();
}
}
class Y extends X {
function foo() {
echo 'Y::foo()';
}
}
$x = new Y();
$x->bar();
?>
Hier ist ein Beispiel für die Unterdrückung des polymorphen Verhaltens mithilfe self
von Elementfunktionen:
<?php
class X {
function foo() {
echo 'X::foo()';
}
function bar() {
self::foo();
}
}
class Y extends X {
function foo() {
echo 'Y::foo()';
}
}
$x = new Y();
$x->bar();
?>
Die Idee ist, dass
$this->foo()
diefoo()
Member-Funktion aufgerufen wird, was auch immer der genaue Typ des aktuellen Objekts ist. Wenn das Objekt von isttype X
, ruft es somit aufX::foo()
. Wenn das Objekt von isttype Y
, ruft es aufY::foo()
. Aber mit self :: foo ()X::foo()
wird immer aufgerufen.
Von http://www.phpbuilder.com/board/showthread.php?t=10354489 :
Von http://board.phpbuilder.com/member.php?145249-laserlight
self
wird mit dem Bereichsauflösungsoperator verwendet ::
, um auf die aktuelle Klasse zu verweisen. Dies kann sowohl in statischen als auch in nicht statischen Kontexten erfolgen. Darüber hinaus ist es völlig legal, $this
statische Methoden aufzurufen (aber keine Referenzfelder).
$this::
?
Das Schlüsselwort self bezieht sich NICHT nur auf die 'aktuelle Klasse', zumindest nicht in einer Weise, die Sie auf statische Mitglieder beschränkt. self
Bietet im Kontext eines nicht statischen Elements auch eine Möglichkeit, die vtable ( siehe Wiki auf vtable ) für das aktuelle Objekt zu umgehen . So wie Sie parent::methodName()
die übergeordnete Version einer Funktion aufrufen können, können Sie auch self::methodName()
die aktuelle Klassenimplementierung einer Methode aufrufen.
class Person {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function getTitle() {
return $this->getName()." the person";
}
public function sayHello() {
echo "Hello, I'm ".$this->getTitle()."<br/>";
}
public function sayGoodbye() {
echo "Goodbye from ".self::getTitle()."<br/>";
}
}
class Geek extends Person {
public function __construct($name) {
parent::__construct($name);
}
public function getTitle() {
return $this->getName()." the geek";
}
}
$geekObj = new Geek("Ludwig");
$geekObj->sayHello();
$geekObj->sayGoodbye();
Dies wird Folgendes ausgeben:
Hallo, ich bin Ludwig der Geek
Auf Wiedersehen von Ludwig die Person
sayHello()
Verwendet den $this
Zeiger, sodass die vtable zum Aufrufen aufgerufen wird Geek::getTitle()
.
sayGoodbye()
verwendet self::getTitle()
, daher wird die vtable nicht verwendet und Person::getTitle()
aufgerufen. In beiden Fällen handelt es sich um die Methode eines instanziierten Objekts und wir haben Zugriff auf den $this
Zeiger innerhalb der aufgerufenen Funktionen.
self
sich befindet" / "die Klassendefinition, die ein wörtlicher Teil von" ist, als auch als "die Klasse des Objekts" (was tatsächlich der Fall wäre static
) verstanden werden kann.
$this::
?
$this::
; Alle möglichen Fälle werden bereits durch häufig verwendete Syntaxen abgedeckt. Je nachdem , was Sie meinen, Verwendung $this->
, self::
oder static::
.
NICHT VERWENDEN self::
, verwendenstatic::
Es gibt noch einen weiteren Aspekt des Selbst: der erwähnenswert ist. Ärgerlicherweise self::
bezieht sich der Geltungsbereich zum Zeitpunkt der Definition und nicht zum Zeitpunkt der Ausführung . Betrachten Sie diese einfache Klasse mit zwei Methoden:
class Person
{
public static function status()
{
self::getStatus();
}
protected static function getStatus()
{
echo "Person is alive";
}
}
Wenn wir anrufen, sehen Person::status()
wir "Person lebt". Überlegen Sie nun, was passiert, wenn wir eine Klasse erstellen, die davon erbt:
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
Beim Aufrufen wird Deceased::status()
erwartet, dass "Person ist verstorben" angezeigt wird. Wir sehen jedoch "Person lebt", da der Bereich die ursprüngliche Methodendefinition enthält, als der Aufruf von self::getStatus()
definiert wurde.
PHP 5.3 hat eine Lösung. Der static::
Auflösungsoperator implementiert "späte statische Bindung", was eine ausgefallene Art zu sagen ist, dass sie an den Umfang der aufgerufenen Klasse gebunden ist. Ändern Sie die Zeile in status()
zu static::getStatus()
, und die Ergebnisse sind das, was man erwarten würde. In älteren Versionen von PHP müssen Sie einen Kludge finden, um dies zu tun.
Siehe PHP-Dokumentation
Also, um die Frage nicht wie gestellt zu beantworten ...
$this->
bezieht sich auf das aktuelle Objekt (eine Instanz einer Klasse), während static::
sich auf eine Klasse bezieht
getStatus
Methode als eine, die ich für eine Klasseninstanz aufrufen würde, nicht für eine Klasse.
self::
, können Sie das weniger bekommen verwirrenderweise unter Verwendung des spezifischen Klassennamens, z MyClass::
. B.
Um wirklich zu verstehen, worüber wir sprechen, wenn wir über self
versus sprechen $this
, müssen wir uns tatsächlich mit dem befassen, was auf konzeptioneller und praktischer Ebene vor sich geht. Ich habe nicht das Gefühl, dass eine der Antworten dies angemessen macht. Hier ist mein Versuch.
Lassen Sie uns zunächst darüber sprechen, was eine Klasse und ein Objekt sind.
Was ist eine Klasse ? Viele Leute definieren es als Blaupause oder Vorlage für ein Objekt. In der Tat können Sie hier mehr über Klassen in PHP lesen . Und bis zu einem gewissen Grad ist es das wirklich. Schauen wir uns eine Klasse an:
class Person {
public $name = 'my name';
public function sayHello() {
echo "Hello";
}
}
Wie Sie sehen können, gibt es für diese Klasse eine Eigenschaft namens $name
und eine Methode (Funktion) sayHello()
.
Es ist sehr wichtig zu beachten, dass die Klasse eine statische Struktur ist. Dies bedeutet, dass die Person
einmal definierte Klasse überall, wo Sie sie betrachten, immer dieselbe ist.
Ein Objekt hingegen ist eine sogenannte Instanz einer Klasse. Das bedeutet, dass wir den "Entwurf" der Klasse nehmen und daraus eine dynamische Kopie erstellen. Diese Kopie ist jetzt speziell an die Variable gebunden, in der sie gespeichert ist. Daher sind alle Änderungen an einer Instanz lokal für diese Instanz.
$bob = new Person;
$adam = new Person;
$bob->name = 'Bob';
echo $adam->name; // "my name"
Wir erstellen neue Instanzen einer Klasse mit dem new
Operator.
Daher sagen wir, dass eine Klasse eine globale Struktur und ein Objekt eine lokale Struktur ist. Mach dir keine Sorgen um diese lustige ->
Syntax, wir werden gleich darauf eingehen.
Eine andere Sache, über die wir sprechen sollten, ist, dass wir überprüfen können , ob eine Instanz instanceof
eine bestimmte Klasse ist: $bob instanceof Person
die einen Booleschen Wert zurückgibt, wenn die $bob
Instanz mit der Person
Klasse oder einem untergeordneten Element von erstellt wurde Person
.
Lassen Sie uns ein wenig untersuchen, was eine Klasse tatsächlich enthält. Es gibt 5 Arten von "Dingen", die eine Klasse enthält:
Eigenschaften - Stellen Sie sich diese als Variablen vor, die jede Instanz enthalten wird.
class Foo {
public $bar = 1;
}
Statische Eigenschaften - Stellen Sie sich diese als Variablen vor, die auf Klassenebene gemeinsam genutzt werden. Dies bedeutet, dass sie niemals von jeder Instanz kopiert werden.
class Foo {
public static $bar = 1;
}
Methoden - Dies sind Funktionen, die jede Instanz enthält (und mit Instanzen arbeitet).
class Foo {
public function bar() {}
}
Statische Methoden - Dies sind Funktionen, die von der gesamten Klasse gemeinsam genutzt werden. Sie arbeiten nicht mit Instanzen, sondern nur mit den statischen Eigenschaften.
class Foo {
public static function bar() {}
}
Konstanten - Klassenaufgelöste Konstanten. Hier nicht tiefer gehen, sondern der Vollständigkeit halber hinzufügen:
class Foo {
const BAR = 1;
}
Im Grunde speichern wir Informationen über den Klassen- und Objektcontainer mithilfe von "Hinweisen" zu statischen Informationen, die angeben, ob die Informationen gemeinsam genutzt werden (und daher statisch sind) oder nicht (und daher dynamisch).
Innerhalb einer Methode wird die Instanz eines Objekts durch die $this
Variable dargestellt. Der aktuelle Status dieses Objekts ist vorhanden, und das Mutieren (Ändern) einer Eigenschaft führt zu einer Änderung dieser Instanz (jedoch nicht anderer).
Wenn eine Methode statisch aufgerufen wird, ist die $this
Variable nicht definiert . Dies liegt daran, dass einem statischen Aufruf keine Instanz zugeordnet ist.
Das Interessante dabei ist, wie statische Anrufe getätigt werden. Sprechen wir also darüber, wie wir auf den Staat zugreifen:
Nachdem wir diesen Status gespeichert haben, müssen wir darauf zugreifen. Dies kann etwas knifflig werden (oder weit mehr als ein bisschen). Teilen wir dies also in zwei Gesichtspunkte auf: von außerhalb einer Instanz / Klasse (z. B. von einem normalen Funktionsaufruf oder vom globalen Bereich) und innerhalb einer Instanz / class (aus einer Methode für das Objekt).
Von außerhalb einer Instanz / Klasse sind unsere Regeln recht einfach und vorhersehbar. Wir haben zwei Operatoren und jeder teilt uns sofort mit, ob es sich um eine Instanz oder eine statische Klasse handelt:
->
- Objektoperator - Dies wird immer verwendet, wenn wir auf eine Instanz zugreifen.
$bob = new Person;
echo $bob->name;
Es ist wichtig zu beachten, dass das Aufrufen Person->foo
keinen Sinn ergibt (da Person
es sich um eine Klasse handelt, nicht um eine Instanz). Daher ist dies ein Analysefehler.
::
- Bereichsauflösungsoperator - Wird immer verwendet, um auf eine statische Eigenschaft oder Methode der Klasse zuzugreifen.
echo Foo::bar()
Darüber hinaus können wir eine statische Methode für ein Objekt auf dieselbe Weise aufrufen:
echo $foo::bar()
Es ist äußerst wichtig zu beachten, dass die Instanz des Objekts , wenn wir dies von außen tun , vor der bar()
Methode verborgen bleibt . Das heißt, es ist genau das gleiche wie beim Laufen:
$class = get_class($foo);
$class::bar();
Daher $this
ist im statischen Aufruf nicht definiert.
Hier ändern sich die Dinge ein bisschen. Es werden dieselben Operatoren verwendet, aber ihre Bedeutung wird erheblich unscharf.
Der Objektoperator ->
wird weiterhin verwendet, um den Instanzstatus des Objekts aufzurufen.
class Foo {
public $a = 1;
public function bar() {
return $this->a;
}
}
Das Aufrufen der bar()
Methode für $foo
(eine Instanz von Foo
) mit dem Objektoperator: $foo->bar()
führt zur Version von der Instanz von $a
.
So erwarten wir es also.
Die Bedeutung des ::
Operators ändert sich jedoch. Dies hängt vom Kontext des Aufrufs der aktuellen Funktion ab:
In einem statischen Kontext
In einem statischen Kontext sind alle mit verwendeten Anrufe ::
auch statisch. Schauen wir uns ein Beispiel an:
class Foo {
public function bar() {
return Foo::baz();
}
public function baz() {
return isset($this);
}
}
Der Aufruf Foo::bar()
wird der Anruf baz()
statisch Methode, und daher $this
wird nicht aufgefüllt werden. Es ist erwähnenswert, dass dies in neueren Versionen von PHP (5.3+) einen E_STRICT
Fehler auslöst , da wir nicht statische Methoden statisch aufrufen.
Innerhalb eines Instanzkontexts
In einem Instanzkontext hingegen ::
hängen Anrufe, die mit ausgeführt werden, vom Empfänger des Anrufs ab (der Methode, die wir aufrufen). Wenn die Methode definiert ist als static
, wird ein statischer Aufruf verwendet. Ist dies nicht der Fall, werden die Instanzinformationen weitergeleitet.
Wenn Sie sich also den obigen Code ansehen, $foo->bar()
wird der Aufruf zurückgegeben true
, da der "statische" Aufruf innerhalb eines Instanzkontexts erfolgt.
Sinn ergeben? Das habe ich nicht gedacht. Es ist verwirrend.
Da das Zusammenbinden von Elementen mithilfe von Klassennamen ziemlich schmutzig ist, bietet PHP drei grundlegende "Verknüpfungs" -Schlüsselwörter, um die Auflösung des Bereichs zu vereinfachen.
self
- Dies bezieht sich auf den aktuellen Klassennamen. Ist self::baz()
also dasselbe wie Foo::baz()
innerhalb der Foo
Klasse (jede Methode darauf).
parent
- Dies bezieht sich auf das übergeordnete Element der aktuellen Klasse.
static
- Dies bezieht sich auf die aufgerufene Klasse. Dank der Vererbung können untergeordnete Klassen Methoden und statische Eigenschaften überschreiben. static
Wenn wir sie also anstelle eines Klassennamens aufrufen, können wir feststellen, woher der Anruf stammt und nicht auf der aktuellen Ebene.
Der einfachste Weg, dies zu verstehen, besteht darin, sich einige Beispiele anzusehen. Lassen Sie uns eine Klasse auswählen:
class Person {
public static $number = 0;
public $id = 0;
public function __construct() {
self::$number++;
$this->id = self::$number;
}
public $name = "";
public function getName() {
return $this->name;
}
public function getId() {
return $this->id;
}
}
class Child extends Person {
public $age = 0;
public function __construct($age) {
$this->age = $age;
parent::__construct();
}
public function getName() {
return 'child: ' . parent::getName();
}
}
Jetzt betrachten wir hier auch die Vererbung. Ignorieren Sie für einen Moment, dass dies ein schlechtes Objektmodell ist, aber schauen wir uns an, was passiert, wenn wir damit spielen:
$bob = new Person;
$bob->name = "Bob";
$adam = new Person;
$adam->name = "Adam";
$billy = new Child;
$billy->name = "Billy";
var_dump($bob->getId()); // 1
var_dump($adam->getId()); // 2
var_dump($billy->getId()); // 3
Der ID-Zähler wird also von beiden Instanzen und den untergeordneten Elementen gemeinsam genutzt (da wir self
für den Zugriff darauf verwenden. Wenn wir ihn verwenden static
, können wir ihn in einer untergeordneten Klasse überschreiben).
var_dump($bob->getName()); // Bob
var_dump($adam->getName()); // Adam
var_dump($billy->getName()); // child: Billy
Beachten Sie, dass wir die Person::getName()
Instanzmethode jedes Mal ausführen . Aber wir verwenden das parent::getName()
, um es in einem der Fälle zu tun (dem untergeordneten Fall). Dies macht diesen Ansatz leistungsfähig.
Beachten Sie, dass der aufrufende Kontext bestimmt, ob eine Instanz verwendet wird. Deshalb:
class Foo {
public function isFoo() {
return $this instanceof Foo;
}
}
Ist nicht immer wahr.
class Bar {
public function doSomething() {
return Foo::isFoo();
}
}
$b = new Bar;
var_dump($b->doSomething()); // bool(false)
Jetzt ist es hier wirklich komisch. Wir rufen eine andere Klasse auf, aber die $this
, die an die Foo::isFoo()
Methode übergeben wird, ist die Instanz von $bar
.
Dies kann alle möglichen Fehler und konzeptionelle WTF-Fehler verursachen. Also ich sehr empfehlen würde die Vermeidung ::
Operator aus Instanzmethoden auf irgendetwas außer den drei virtuellen „short-cut“ keywords ( static
, self
, und parent
).
Beachten Sie, dass statische Methoden und Eigenschaften von allen gemeinsam genutzt werden. Das macht sie im Grunde zu globalen Variablen. Mit den gleichen Problemen, die mit Globals kommen. Daher würde ich sehr zögern, Informationen in statischen Methoden / Eigenschaften zu speichern, es sei denn, Sie sind damit einverstanden, dass sie wirklich global sind.
Im Allgemeinen möchten Sie das verwenden, was als Late-Static-Binding bezeichnet wird, indem Sie static
anstelle von verwenden self
. Beachten Sie jedoch, dass sie nicht dasselbe sind. Daher ist es sehr kurzsichtig , zu sagen, dass immer verwenden static
statt verwenden self
. Halten Sie stattdessen an und überlegen Sie, welchen Anruf Sie tätigen möchten, und überlegen Sie, ob untergeordnete Klassen diese statische Auflösung überschreiben können Anruf.
Schade, geh zurück und lies es. Es mag zu lang sein, aber es ist so lang, weil dies ein komplexes Thema ist
Ok, gut. Kurz gesagt, self
wird verwendet , um das Bezug der aktuellen Klassennamen innerhalb einer Klasse, in der, wie $this
auf die aktuelle Objekt verweist Instanz . Beachten Sie, dass dies self
eine Verknüpfung zum Kopieren / Einfügen ist. Sie können es sicher durch Ihren Klassennamen ersetzen, und es wird gut funktionieren. Ist $this
aber eine dynamische Variable, die nicht im Voraus bestimmt werden kann (und möglicherweise nicht einmal Ihre Klasse ist).
Wenn der Objektoperator ( ->
) verwendet wird, wissen Sie immer , dass es sich um eine Instanz handelt. Wenn der Scope-Resolution-Operator verwendet wird ( ::
), benötigen Sie weitere Informationen zum Kontext (befinden wir uns bereits in einem Objektkontext? Befinden wir uns außerhalb eines Objekts? Usw.).
$this
wird nicht definiert, wenn Sie "Strikte Standards" befolgen und keine statischen Methoden aufrufen, die nicht als statisch definiert sind. Ich sehe das Ergebnis, das Sie hier erklärt haben: 3v4l.org/WeHVM Einverstanden, wirklich komisch.
Foo::isFoo()
statisch genannt, $this
wird es nicht definiert. Das ist meiner Meinung nach intuitiver. - Ein anderes Ergebnis ergibt sich, wenn Bar
von Foo
. Dann Foo::isFoo()
würde sich der Aufruf tatsächlich im Instanzkontext befinden (nicht spezifisch für PHP7).
self
(nicht $ self) bezieht sich auf die Art der Klasse, wo , wie $this
auf die aktuelle bezieht Instanz der Klasse. self
dient zur Verwendung in statischen Elementfunktionen, um Ihnen den Zugriff auf statische Elementvariablen zu ermöglichen. $this
wird in nicht statischen Elementfunktionen verwendet und verweist auf die Instanz der Klasse, für die die Elementfunktion aufgerufen wurde.
Da this
es sich um ein Objekt handelt, verwenden Sie es wie folgt:$this->member
Da self
es sich nicht um ein Objekt handelt, handelt es sich im Grunde genommen um einen Typ, der automatisch auf die aktuelle Klasse verweist. Sie verwenden ihn wie folgt:self::member
$this->
wird verwendet, um auf eine bestimmte Instanz der Variablen (Mitgliedsvariablen) oder Methoden einer Klasse zu verweisen.
Example:
$derek = new Person();
$ derek ist jetzt eine bestimmte Instanz von Person. Jede Person hat einen Vor- und einen Nachnamen, aber $ derek hat einen bestimmten Vor- und Nachnamen (Derek Martin). Innerhalb der $ derek-Instanz können wir diese als $ this-> first_name und $ this-> last_name bezeichnen
ClassName :: wird verwendet, um auf diesen Klassentyp und seine statischen Variablen, statische Methoden, zu verweisen. Wenn es hilft, können Sie das Wort "statisch" mental durch "geteilt" ersetzen. Da sie gemeinsam genutzt werden, können sie nicht auf $ this verweisen, das sich auf eine bestimmte Instanz bezieht (nicht freigegeben). Statische Variablen (dh statische $ db_connection) können von allen Instanzen eines Objekttyps gemeinsam genutzt werden. Beispielsweise teilen sich alle Datenbankobjekte eine einzige Verbindung (statische $ Verbindung).
Statische Variablen Beispiel: Stellen Sie sich vor, wir haben eine Datenbankklasse mit einer einzelnen Mitgliedsvariablen: static $ num_connections; Fügen Sie dies nun in den Konstruktor ein:
function __construct()
{
if(!isset $num_connections || $num_connections==null)
{
$num_connections=0;
}
else
{
$num_connections++;
}
}
So wie Objekte Konstruktoren haben, haben sie auch Destruktoren, die ausgeführt werden, wenn das Objekt stirbt oder nicht gesetzt ist:
function __destruct()
{
$num_connections--;
}
Jedes Mal, wenn wir eine neue Instanz erstellen, wird unser Verbindungszähler um eins erhöht. Jedes Mal, wenn wir eine Instanz zerstören oder nicht mehr verwenden, wird der Verbindungszähler um eins verringert. Auf diese Weise können wir die Anzahl der Instanzen des Datenbankobjekts überwachen, mit denen wir arbeiten:
echo DB::num_connections;
Da $ num_connections statisch (gemeinsam genutzt) ist, gibt es die Gesamtzahl der aktiven Datenbankobjekte wieder. Möglicherweise wurde diese Technik verwendet, um Datenbankverbindungen für alle Instanzen einer Datenbankklasse freizugeben. Dies geschieht, weil das Erstellen der Datenbankverbindung sehr lange dauert. Daher ist es am besten, nur eine zu erstellen und diese freizugeben (dies wird als Singleton-Muster bezeichnet).
Statische Methoden (dh öffentliche statische View :: format_phone_number ($ digits)) können verwendet werden, OHNE zuerst eines dieser Objekte zu instanziieren (dh sie verweisen nicht intern auf $ this).
Beispiel für eine statische Methode:
public static function prettyName($first_name, $last_name)
{
echo ucfirst($first_name).' '.ucfirst($last_name);
}
echo Person::prettyName($derek->first_name, $derek->last_name);
Wie Sie sehen können, weiß die öffentliche statische Funktion PrettyName nichts über das Objekt. Es funktioniert nur mit den Parametern, die Sie übergeben, wie eine normale Funktion, die nicht Teil eines Objekts ist. Warum also die Mühe machen, wenn wir es einfach nicht als Teil des Objekts haben könnten?
SELBST :: Wenn Sie außerhalb des Objekts codieren , das über die statische Methode verfügt, auf die Sie verweisen möchten, müssen Sie es mit dem Objektnamen View :: format_phone_number ($ phone_number) aufrufen. Wenn Sie innerhalb des Objekts codieren , das über die statische Methode verfügt, auf die Sie verweisen möchten, können Sie entweder den Objektnamen View :: format_phone_number ($ pn) oder die Verknüpfung self :: format_phone_number ($ pn) verwenden
Gleiches gilt für statische Variablen: Beispiel: View :: templates_path versus self :: templates_path
Wenn wir in der DB-Klasse auf eine statische Methode eines anderen Objekts verweisen, verwenden wir den Namen des Objekts: Beispiel: Session :: getUsersOnline ();
Wenn die DB-Klasse jedoch auf ihre eigene statische Variable verweisen möchte, sagt sie einfach self: Beispiel: self :: connection;
Hoffe das hilft Dinge aufzuklären :)
$
Zeichen verwenden müssen. Zum Beispielself::$templates_path
Aus diesem Blog-Beitrag :
self
bezieht sich auf die aktuelle Klasseself
kann verwendet werden, um statische Funktionen aufzurufen und statische Elementvariablen zu referenzierenself
kann in statischen Funktionen verwendet werdenself
kann auch das polymorphe Verhalten durch Umgehen der vtable ausschalten$this
bezieht sich auf das aktuelle Objekt$this
kann verwendet werden, um statische Funktionen aufzurufen$this
sollte nicht zum Aufrufen statischer Elementvariablen verwendet werden. Verwenden Sieself
stattdessen.$this
kann nicht in statischen Funktionen verwendet werden
In PHP verwenden Sie das Schlüsselwort self, um auf statische Eigenschaften und Methoden zuzugreifen.
Das Problem ist , dass Sie ersetzen können , $this->method()
mit self::method()
überall, unabhängig davon , obmethod()
statisch deklariert wird oder nicht. Welches sollten Sie also verwenden?
Betrachten Sie diesen Code:
class ParentClass {
function test() {
self::who(); // will output 'parent'
$this->who(); // will output 'child'
}
function who() {
echo 'parent';
}
}
class ChildClass extends ParentClass {
function who() {
echo 'child';
}
}
$obj = new ChildClass();
$obj->test();
In diesem Beispiel self::who()
wird immer 'parent' ausgegeben, während$this->who()
von der Klasse des Objekts abhängt.
Jetzt können wir sehen, dass sich self auf die Klasse bezieht, in der es aufgerufen wird, während es $this
sich auf die Klasse des aktuellen Objekts bezieht .
Daher sollten Sie self nur verwenden, wenn $this
es nicht verfügbar ist oder wenn Sie nicht zulassen möchten, dass Nachkommenklassen die aktuelle Methode überschreiben.
$this
Bezieht sich innerhalb einer Klassendefinition auf das aktuelle Objekt, währendself
sich auf die aktuelle Klasse bezieht.
Es ist erforderlich, mit auf ein Klassenelement zu verweisen self
und mit auf ein Objektelement zu verweisen $this
.
self::STAT // refer to a constant value
self::$stat // static variable
$this->stat // refer to an object variable
Hier ist ein Beispiel für die korrekte Verwendung von $ this und self für nicht statische und statische Elementvariablen:
<?php
class X {
private $non_static_member = 1;
private static $static_member = 2;
function __construct() {
echo $this->non_static_member . ' '
. self::$static_member;
}
}
new X();
?>
Laut http://www.php.net/manual/en/language.oop5.static.php gibt es keine $self
. Es gibt nur $this
, um auf die aktuelle Instanz der Klasse (das Objekt) und self zu verweisen, die verwendet werden können, um auf statische Mitglieder einer Klasse zu verweisen. Hier kommt der Unterschied zwischen einer Objektinstanz und einer Klasse ins Spiel.
Ich glaube, die Frage war nicht, ob Sie das statische Mitglied der Klasse durch Aufrufen aufrufen können ClassName::staticMember
. Die Frage war, was der Unterschied zwischen self::classmember
und ist $this->classmember
.
Zum Beispiel funktionieren beide der folgenden Beispiele fehlerfrei, unabhängig davon, ob Sie self::
oder verwenden$this->
class Person{
private $name;
private $address;
public function __construct($new_name,$new_address){
$this->name = $new_name;
$this->address = $new_address;
}
}
class Person{
private $name;
private $address;
public function __construct($new_name,$new_address){
self::$name = $new_name;
self::$address = $new_address;
}
}
Fatal error: Access to undeclared static property: Person::$name in D:\LAMP\www\test.php on line 16
self
bezieht sich auf die aktuelle Klasse (in der es heißt),
$this
verweist auf das aktuelle Objekt. Sie können statisch anstelle von selbst verwenden. Siehe das Beispiel:
class ParentClass {
function test() {
self::which(); // output 'parent'
$this->which(); // output 'child'
}
function which() {
echo 'parent';
}
}
class ChildClass extends ParentClass {
function which() {
echo 'child';
}
}
$obj = new ChildClass();
$obj->test();
Ausgabe: Eltern Kind
$this
auf bezieht sich auf das aktuelle Objekt.static
bezieht sich auf das aktuelle Objekt.self
bezieht sich auf die genaue Klasse, in der er definiert wurde.parent
bezieht sich auf das übergeordnete Element der genauen Klasse, in der es definiert wurde.Siehe das folgende Beispiel, das die Überlastung zeigt.
<?php
class A {
public static function newStaticClass()
{
return new static;
}
public static function newSelfClass()
{
return new self;
}
public function newThisClass()
{
return new $this;
}
}
class B extends A
{
public function newParentClass()
{
return new 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()); // A
class C extends B
{
public static function newSelfClass()
{
return new self;
}
}
$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"
Meistens möchten Sie sich auf die aktuelle Klasse beziehen, weshalb Sie static
oder verwenden $this
. Es gibt jedoch Zeiten, in denen Sie die ursprüngliche Klasse benötigen, self
unabhängig davon, was sie erweitert. (Sehr, sehr selten)
Da hier niemand über Leistungen sprach, ist hier ein kleiner Maßstab, den ich gemacht habe (5.6):
Name | Time | Percent
----------|---------|---------
$this-> | 0.99163 | 106.23%
self:: | 0.96912 | 103.82%
static:: | 0.93348 | 100%
Das sind die Ergebnisse für 2 000 000 Läufe, und hier ist der Code, den ich verwendet habe:
<?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 = new Tleb\Benchmark\Benchmark(2000000);
class Foo
{
public function calling_this()
{
$this->called();
}
public function calling_self()
{
self::called();
}
public function calling_static()
{
static::called();
}
public static function called()
{
}
}
$b->add('$this->', function () { $foo = new Foo; $foo->calling_this(); });
$b->add('self::', function () { $foo = new Foo; $foo->calling_self(); });
$b->add('static::', function () { $foo = new Foo; $foo->calling_static(); });
$b->run();
1 / 2e9 s = 0.5 ns
diesen Tagen macht
use
Schlüsselwort tbh nicht verwendet habe, aber ich habe kein PHP mehr, um einen Benchmark zu wiederholen, und ich habe keine Lust, ihn neu zu installieren.
Wenn self
es mit dem ::
Operator verwendet wird, bezieht es sich auf die aktuelle Klasse, was sowohl in statischen als auch in nicht statischen Kontexten erfolgen kann. $this
bezieht sich auf das Objekt selbst. Darüber hinaus ist es völlig legal, $this
statische Methoden aufzurufen (aber nicht auf Felder zu verweisen).
Ich bin auf dieselbe Frage gestoßen und die einfache Antwort lautet:
$this
erfordert eine Instanz der Klasseself::
nichtWenn Sie statische Methoden oder statische Attribute verwenden und diese aufrufen möchten, ohne dass ein Objekt der Klasse instanziiert wurde, müssen Sie self:
sie aufrufen, da $this
immer ein Objekt erstellt werden muss.
$this
bezieht sich auf das aktuelle Klassenobjekt, self
bezieht sich auf die aktuelle Klasse (kein Objekt). Die Klasse ist die Blaupause des Objekts. Sie definieren also eine Klasse, aber Sie konstruieren Objekte.
Also mit anderen Worten, verwenden Sie self for static
undthis for none-static members or methods
.
Auch im Child / Parent-Szenario self / parent
wird meistens verwendet, um untergeordnete und übergeordnete Klassenmitglieder und -methoden zu identifizieren.
Zusätzlich seit $this::
noch nicht diskutiert.
Nur zu Informationszwecken, ab PHP 5.3, wenn mit instanziierten Objekten gearbeitet wird, um den aktuellen Bereichswert zu erhalten static::
, kann man alternativ $this::
wie folgt verwenden.
class Foo
{
const NAME = 'Foo';
//Always Foo::NAME (Foo) due to self
protected static $staticName = self::NAME;
public function __construct()
{
echo $this::NAME;
}
public function getStaticName()
{
echo $this::$staticName;
}
}
class Bar extends Foo
{
const NAME = 'FooBar';
/**
* override getStaticName to output Bar::NAME
*/
public function getStaticName()
{
$this::$staticName = $this::NAME;
parent::getStaticName();
}
}
$foo = new Foo; //outputs Foo
$bar = new Bar; //outputs FooBar
$foo->getStaticName(); //outputs Foo
$bar->getStaticName(); //outputs FooBar
$foo->getStaticName(); //outputs FooBar
Die Verwendung des obigen Codes ist keine übliche oder empfohlene Vorgehensweise, sondern dient lediglich der Veranschaulichung seiner Verwendung und dient eher als "Wussten Sie, dass?" in Bezug auf die Frage des Originalplakats.
Es repräsentiert auch die Verwendung von $object::CONSTANT
zum Beispiel echo $foo::NAME;
im Gegensatz zu$this::NAME;
Verwenden self
Sie diese Option, wenn Sie eine Methode einer Klasse aufrufen möchten, ohne ein Objekt / eine Instanz dieser Klasse zu erstellen, wodurch RAM gespart wird (verwenden Sie manchmal self für diesen Zweck). Mit anderen Worten, es wird tatsächlich eine Methode statisch aufgerufen. Verwendung this
für Objektperspektive.
Fall 1: Verwenden self
kann für Klassenkonstanten verwendet werden
Klasse KlasseA { const FIXED_NUMBER = 4; self :: POUNDS_TO_KILOGRAMS }}
Wenn Sie es außerhalb der Klasse aufrufen möchten, verwenden Sie, um classA::POUNDS_TO_KILOGRAMS
auf die Konstanten zuzugreifen
Fall 2: Für statische Eigenschaften
Klasse classC { öffentliche Funktion __construct () { self :: $ _ counter ++; $ this-> num = self :: $ _ counter; }} }}
Nach php.net gibt es drei spezielle Schlüsselwörter in diesem Zusammenhang: self
, parent
und static
. Sie werden verwendet, um über die Klassendefinition auf Eigenschaften oder Methoden zuzugreifen.
$this
Auf der anderen Seite wird eine Instanz und Methoden einer Klasse aufgerufen, solange auf diese Klasse zugegriffen werden kann.
Das Schlüsselwort self :: wird für die aktuelle Klasse verwendet und im Grunde genommen für den Zugriff auf statische Elemente, Methoden und Konstanten. In diesem Fall können Sie das statische Element, die Methode und die Funktionen jedoch nicht aufrufen.
Sie können das Schlüsselwort self :: in einer anderen Klasse verwenden und auf die statischen Elemente, Methoden und Konstanten zugreifen. Wann wird es von der übergeordneten Klasse erweitert und im Fall von $ dieses Schlüsselwort gleich. Sie können auf die nicht statischen Elemente, Methoden und Funktionen einer anderen Klasse zugreifen, wenn diese von der übergeordneten Klasse erweitert werden.
Der unten angegebene Code ist ein Beispiel für self :: und $ this keyword. Kopieren Sie einfach den Code und fügen Sie ihn in Ihre Codedatei ein. Die Ausgabe wird angezeigt.
class cars{
var $doors=4;
static $car_wheel=4;
public function 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());