Frage

In PHP 5, was ist der Unterschied zwischen der Verwendung von self und $this?

Wann ist jeweils angemessen?

War es hilfreich?

Lösung

Kurze Antwort

  

Mit $this auf den aktuellen Bezug zu nehmen   Objekt. Verwenden Sie self auf die Bezug zu nehmen   aktuelle Klasse. Mit anderen Worten, die Verwendung   $this->member für nicht-statische Elemente,   verwenden self::$member für statische Mitglieder.

Voll Antwort

Hier ist ein Beispiel für richtig 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 falsch 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 von Polymorphismus mit $this für Member-Funktionen:

<?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 von Unterdrückung von polymorphen Verhalten durch self für Member-Funktionen mit:

<?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() ruft die foo() Member-Funktion von was auch immer der genaue Typ des aktuellen Objekts. Wenn das Objekt von type X ist, nennt es so X::foo(). Wenn das Objekt von type Y ist, ruft es Y::foo(). Aber mit self :: foo () wird X::foo() immer genannt.

http://www.phpbuilder.com/board/showthread.php ? t = 10354489 :

Mit dem http://board.phpbuilder.com/member.php?145249-laserlight

Andere Tipps

Das Schlüsselwort selbst tut nicht beziehen sich lediglich auf die ‚aktuelle Klasse‘, zumindest nicht in einer Weise, die Sie auf statische Elemente beschränkt. Im Rahmen eines nicht-statisches Element, self bietet auch eine Möglichkeit, die VTable der Umgehung ( siehe Wiki auf VTable ) für das aktuelle Objekt. So wie Sie parent::methodName() rufen die Eltern Version einer Funktion verwenden können, so können Sie self::methodName() rufen Sie die aktuellen Klassen Implementierung eines Verfahrens zu nennen.

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 ausgegeben:

  

Hallo, ich bin Ludwig der Aussenseiter
     Abschied von Ludwig der Person

sayHello() verwendet den $this Zeiger, so wird die V-Tabelle zu nennen Geek::getTitle() aufgerufen. sayGoodbye() verwendet self::getTitle(), so dass die V-Tabelle nicht verwendet wird, und Person::getTitle() genannt wird. In beiden Fällen haben wir es mit dem Verfahren eines instanziierten Objekts und haben Zugriff auf die $this Zeiger innerhalb der aufgerufenen Funktionen.

NICHT self:: verwenden, verwenden static::

Es ist ein weiterer Aspekt der Selbst :: das ist erwähnenswert. Annoyingly self:: bezieht sich auf den Umfang an der Stelle der Definition nicht an dem Punkt 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 Person::status() nennen wir werden sehen „Person lebt“. Betrachten wir nun, was passiert, wenn wir eine Klasse zu machen, die von dieser erbt:

class Deceased extends Person
{

    protected static function getStatus()
    {
        echo "Person is deceased";
    }

}

Deceased::status() aufrufen würden wir erwarten, um zu sehen, „Person ist verstorben“ aber was wir sehen, ist „Person am Leben ist“, wie der Umfang der ursprünglichen Methodendefinition enthält, wenn Aufruf self::getStatus() definiert wurde.

PHP 5.3 hat eine Lösung. static:: Operator implementiert „späte statische Bindung“, die eine andere Art zu sagen, dass es auf den Umfang der Klasse gebunden nennt. Ändern Sie die Zeile in status() static::getStatus() und die Ergebnisse sind das, was man erwarten würde. In älteren Versionen von PHP finden Sie eine Flickschusterei, dies zu tun finden müssen.

Siehe PHP Dokumentation

So ist die Frage nicht zu beantworten, wie gefragt ...

$this-> bezieht sich auf das aktuelle Objekt (eine Instanz einer Klasse), während static:: auf eine Klasse verweist

Um wirklich zu verstehen, was wir reden, wenn wir über self gegen $this sprechen, müssen wir in wirklich graben, was auf konzeptioneller vor sich geht und praktischer Ebene. Ich fühle mich nicht wirklich eine der Antworten dies tun, angemessen, also hier ist mein Versuch.

Lassen Sie uns damit beginnen zu reden, was ein Klasse und ein Objekt ist.

Klassen und Objekte, Konzeptionell

Also, was ist a Klasse ? Viele Menschen definieren es als Entwurf oder template für ein Objekt. In der Tat können Sie mehr über Klassen in PHP Hier lesen . Und zu einem gewissen Grad das ist, was es wirklich ist. Schauen wir uns eine Klasse aussehen:

class Person {
    public $name = 'my name';
    public function sayHello() {
        echo "Hello";
    }
}

Wie Sie sehen können, gibt es eine Eigenschaft auf dieser Klasse genannt $name und ein Verfahren (Funktion) genannt sayHello().

Es ist sehr wichtig, dass die Klasse beachten ist eine statische Struktur. Was bedeutet, dass die Klasse Person, einmal definiert, immer und überall das gleiche ist man es betrachtet.

Ein Objekt auf der anderen Seite ist das, was ein Beispiel genannt eine Klasse. Was das bedeutet, ist, dass wir den „Bauplan“ der Klasse zu nehmen, und es verwenden, eine dynamische Kopie zu machen. Diese Kopie wird nun speziell auf die Variable gebunden es in gespeichert ist. Daher werden alle Änderungen an einem Instanz auf diese Instanz lokal ist.

$bob = new Person;
$adam = new Person;
$bob->name = 'Bob';
echo $adam->name; // "my name"

Wir schaffen neue Instanzen eine Klasse mit dem new Operator.

Deshalb sagen wir, dass eine Klasse eine globale Struktur ist, und ein Objekt ist eine lokale Struktur. Sie nicht über diese lustige -> Syntax Sorge, wir gehen in die in ein wenig gehen.

Eine andere Sache, über die wir sprechen sollten, ist, dass wir überprüfen , wenn eine Instanz ein instanceof ist eine besondere Klasse: $bob instanceof Person, die einen Booleschen Wert zurück, wenn die $bob Instanz gemacht wurde die Person-Klasse, < em> oder ein Kind Person.

Definition von Staat

Lassen Sie uns also ein wenig in graben, was eine Klasse tatsächlich enthält. Es gibt 5 Arten von „Dingen“, dass eine Klasse enthält:

  1. Eigenschaften -. Von diesen als Variablen Denken Sie, dass jede Instanz enthält

    class Foo {
        public $bar = 1;
    }
    
  2. Statische Eigenschaften - diese als Variablen denken, dass auf der Ebene der Klassen geteilt werden. Was bedeutet, dass sie von jeder Instanz nie kopiert werden.

    class Foo {
        public static $bar = 1;
    }
    
  3. Methoden -. Dies sind Funktionen, die jede Instanz (und arbeitet mit Instanzen) enthält

    class Foo {
        public function bar() {}
    }
    
  4. Statische Methoden - Dies sind Funktionen, die über die gesamte Klasse geteilt werden. Sie tun nicht arbeiten auf Instanzen, sondern auf die statischen Eigenschaften nur.

    class Foo {
        public static function bar() {}
    }
    
  5. Konstanten - Klasse aufgelöst Konstanten. Nicht tiefer gehen jeder hier, aber das Hinzufügen der Vollständigkeit halber:

    class Foo {
        const BAR = 1;
    }
    

Also im Grunde wir die Speicherung von Informationen über die Klasse und Objektcontainer mit „Hinweisen“ über statisch , die angeben, ob die Informationen gemeinsam genutzt werden (und somit statisch) oder nicht (und damit dynamisch).

Staat und Methoden

Innerhalb eines Verfahrens, einer Instanz des Objekts wird durch die $this Variable dargestellt. Der aktuelle Zustand des Objekts ist da, und mutieren (verändern) jede Eigenschaft wird in diesem Fall zu einer Änderung (aber nicht andere).

Wenn eine Methode statisch aufgerufen wird, die $this Variable ist nicht definiert . Dies ist, weil es keine Instanz ist mit einem statischen Anruf zugeordnet ist.

Das Interessante daran ist, wie statische Anrufe gemacht werden. Also lassen Sie uns darüber sprechen, wie wir den Zustand zugreifen:

Zugriff auf staatliche

So, jetzt haben wir diesen Zustand gespeichert haben, müssen wir darauf zugreifen. Dies kann erhaltenein bisschen schwierig (oder Weg Mehr als nur ein bisschen), ist dies in zwei Aussichtspunkte lassen aufgeteilt: von außerhalb einer Instanz / Klasse (sagt sich von einem normalen Funktionsaufruf oder aus dem globalen Bereich), und innerhalb einer Instanz / Klasse (von innerhalb einer Methode für das Objekt).

Von außerhalb einer Instanz / Klasse

Von außen eine Instanz / Klasse, sind unsere Regeln ziemlich einfach und vorhersehbar. Wir haben zwei Operatoren und jeder sagt uns sofort, wenn wir mit einer Instanz oder einer Klasse zu tun haben statisch:

  • -> - Objekt-Operator -. Dies wird immer dann verwendet, wenn wir eine Instanz zuzugreifst

    $bob = new Person;
    echo $bob->name;
    

    Es ist wichtig zu beachten, dass Person->foo Aufruf nicht sinnvoll (da Person eine Klasse ist, keine Instanz). Deshalb, das ist ein Parse-Fehler.

  • :: - Rahmen-Auflösung-Operator -. Dies wird immer verwendet, um eine Klasse statische Eigenschaft oder eine Methode für den Zugriff auf

    echo Foo::bar()
    

    Darüber hinaus können wir eine statische Methode für ein Objekt in der gleichen Art und Weise nennen:

    echo $foo::bar()
    

    Es ist extrem zu beachten, dass, wenn wir das tun von außen , das Instanz-Objekt aus der bar() Methode verborgen ist. Was bedeutet, dass es genau die gleichen wie Laufen:

    $class = get_class($foo);
    $class::bar();
    

Daher wird $this nicht in dem statischen Aufruf definiert.

Von Innerhalb einer Instanz / Klasse

Die Dinge ändern sich hier ein wenig. Die gleichen Betreiber verwendet werden, aber ihre Bedeutung wird deutlich verschwommen.

Der Objekt-Operator -> noch verwendet wird, Anrufe auf die Objektinstanz Zustand zu machen.

class Foo {
    public $a = 1;
    public function bar() {
        return $this->a;
    }
}

Der Aufruf der Methode bar() auf $foo (eine Instanz von Foo) mit dem Objekt-Operator: $foo->bar() in der Instanz-Version $a führen

.

Das ist also, wie wir es erwarten.

Die Bedeutung des :: Betreiber obwohl Änderungen. Es hängt vom Kontext des Anrufs auf die aktuelle Funktion:

  • Innerhalb eines statischen Kontext

    In einem statischen Kontext, werden alle Anrufe :: verwendet, wird auch statisch sein. Lassen Sie uns ein Beispiel an:

    class Foo {
        public function bar() {
            return Foo::baz();
        }
        public function baz() {
            return isset($this);
        }
    }
    

    Beim Foo::bar() die baz() Methode statisch nennen, und daher wird $this nicht bestückt werden. Es ist erwähnenswert, dass in neueren Versionen von PHP (5.3+), wird dies einen E_STRICT Fehler auslösen, weil wir nicht-statische Methoden statisch sind aufgerufen wird.

  • Innerhalb einer Instanz Kontext

    Innerhalb eines Instanz-Kontextes auf der anderen Seite, Anrufe :: Verwendung hängen von dem Empfänger des Anrufs (die Methode Wir nennen). Wenn das Verfahren als static definiert ist, dann wird es einen statischen Aufruf verwenden. Wenn es nicht ist, wird es die Instanzinformationen übermitteln.

    Also, im obigen Code suchen, $foo->bar() Aufruf wird true zurückkehren, da der „statische“ Aufruf geschieht innerhalb einer Instanz Kontext.

Sinn? Haben Sie nicht denken so. Es ist verwirrend.

Short-Cut Keywords

Weil alles zusammen zu binden Namen Klasse ziemlich schmutzig ist, PHP bietet 3 basic „Abkürzung“ keywords Umfang der Lösung zu erleichtern.

  • self - Dies bezieht sich auf den aktuellen Klassennamen. So self::baz() ist die gleiche wie Foo::baz() innerhalb der Foo Klasse (jede Methode auf sie).

  • parent - Dies bezieht sich auf die Eltern der aktuellen Klasse.

  • static - Dies bezieht sich auf die genannte Klasse. Dank der Vererbung können geordneten Klassen außer Kraft setzen Methoden und statische Eigenschaften. So nennt sie mit static anstelle einem Klassennamen ermöglicht es uns, zu lösen, woher der Anruf kam, anstatt die aktuelle Ebene.

Beispiele

Der einfachste Weg, dies zu verstehen, ist an einigen Beispielen zu suchen beginnen. Lassen Sie uns eine Klasse wä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 suchen wir auch bei Erbschaft hier. Ignorieren für einen Moment, dass dies ein schlechtes Objektmodell ist, aber sie schaut, was passiert, wenn wir mit diesem 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

So ist der ID-Zähler wird über beiden Instanzen und die Kinder gemeinsam genutzt (weil wir verwenden self darauf zuzugreifen. Wenn wir static verwendet, könnten wir es 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() sind Ausführung Instanz Methode jedes Mal. Aber wir sind mit dem parent::getName(), es zu tun in einem der Fälle (das Kind Fall). Dies ist, was macht diesen Ansatz stark.

Ein Wort der Warnung # 1

Beachten Sie, dass der anrufende Kontext ist, was bestimmt, ob eine Instanz verwendet wird. Deshalb:

class Foo {
    public function isFoo() {
        return $this instanceof Foo;
    }
}

Ist das nicht immer wahr.

class Bar {
    public function doSomething() {
        return Foo::isFoo();
    }
}
$b = new Bar;
var_dump($b->doSomething()); // bool(false)

Nun ist es wirklich seltsam hier. Wir nennen eine andere Klasse, aber der $this, die die Foo::isFoo() Methode übergeben wird ist die Instanz von $bar.

Dies kann alle möglichen Fehler verursachen und konzeptionelle WTF-ery. Also würde ich in hohem Grade die :: Operator aus Instanzmethoden auf irgendetwas außer den drei virtuellen „short-cut“ keywords (static, self und parent) schlagen vor, zu vermeiden.

Ein Wort der Warnung # 2

Beachten Sie, dass statische Methoden und Eigenschaften von allen geteilt werden. Das macht sie im Grunde globale Variablen. Mit all den gleichen Problemen, die mit Globals kommen. So würde ich wirklich zögern, Informationen zu speichern, in statischen Methoden / Eigenschaften, wenn Sie bequem sind damit wirklich global zu sein.

Wort der Vorsicht # 3

Im Allgemeinen Sie werden verwenden, was als Spät-Static-Bindung bekannt ist durch static statt self verwenden. Aber beachten Sie, dass sie nicht die gleiche Sache sind, so sagen „immer static anstelle von self ist wirklich kurzsichtig. Stattdessen stoppen und denken über den Anruf, den Sie machen wollen und denken, wenn Sie untergeordnete Klassen wollen außer Kraft setzen zu können, dass statisch aufgelöst Anruf.

TL / DR

Schade, gehen Sie zurück und lesen Sie es. Es kann zu lang sein, aber es ist so lang, weil dies ein komplexes Thema ist

TL / DR # 2

Ok, gut. Kurz gesagt, wird self verwendet Referenz der aktuelle Klassenname in einer Klasse, wo als $this auf das aktuelle Objekt verweist Instanz . dass self Hinweis ist ein copy / paste Kurzschnitt. Sie können es mit Ihrem Klassennamen sicher ersetzen, und es wird gut funktionieren. Aber $this ist eine dynamische Variable, die vor der Zeit nicht ermittelt werden kann (und vielleicht nicht einmal Ihre Klasse sein).

TL / DR # 3

Wenn das Objekt-Operator verwendet wird (->), dann Sie immer wissen Sie mit einer Instanz zu tun hat. Wenn der Umfang auflösender-Operator verwendet wird (::), können Sie mehr Informationen über den Kontext benötigen (wir sind in einem Objekt-Kontext schon? Sind wir außerhalb eines Objekts? Usw.).

self (nicht $ self) bezieht sich auf die type der Klasse, wo als $this auf die aktuelle bezieht Instanz der Klasse. self ist für den Einsatz in statischen Member-Funktionen, damit Sie statische Member-Variablen zuzugreifen. $this wird in nicht-statischen Elementfunktionen verwendet wird, und ist ein Hinweis auf die Instanz der Klasse, auf die die Elementfunktion aufgerufen wurde.

Da this ein Objekt ist, verwenden Sie es wie: $this->member

Da self kein Objekt ist, es ist im Grunde eine Art, die auf die aktuelle Klasse bezieht sich automatisch, Sie verwenden Sie es wie: self::member

$this-> verwendet wird, um eine bestimmte Instanz einer Klasse Variablen (Membervariablen) oder Methoden zu beziehen.

Example: 
$derek = new Person();

$ derek ist jetzt eine bestimmte Instanz Person. Jede Person hat einen first_name und last_name, aber $ derek hat eine spezifische first_name und last_name (Derek Martin). Im Innern des $ derek Beispiel können wir die als $ this-> first_name beziehen und $ this-> last_name

Klassenname :: verwendet wird, um diese Art von Klasse zu beziehen, und seinen statischen Variablen, statischen Methoden. Wenn es hilft, können Sie mental das Wort „statisch“ mit „shared“ ersetzen. Weil sie geteilt werden, können sie nicht auf $ dieses beziehen, die auf eine bestimmte Instanz bezieht sich (nicht gemeinsam). Statische Variablen (das heißt static $ db_connection) kann unter allen Instanzen einer Art von Objekt geteilt werden. Zum Beispiel teilen alle Datenbankobjekte eine einzige Verbindung (static $ Verbindung).

Statische Variablen Beispiel: Täuschen wir eine Datenbank-Klasse mit einem einzigen Element Variable: static $ num_connections; Jetzt setzen diese im Konstruktor:

function __construct()
{
    if(!isset $num_connections || $num_connections==null)
    {
        $num_connections=0;
    }
    else
    {
        $num_connections++;
    }
}

So wie Objekte haben Konstrukteure, sie haben auch Destruktoren, die ausgeführt werden, wenn das Objekt stirbt oder ist nicht gesetzt:

function __destruct()
{
    $num_connections--;
}

Jedes Mal, wenn wir eine neue Instanz erstellen, wird es unsere Verbindungszähler um eins erhöht. Jedes Mal, wenn wir eine Instanz zerstören oder nicht mehr verwenden, wird die Verbindung Zähler um eins zu verringern. Auf diese Weise können wir die Anzahl der Instanzen des Datenbankobjekts überwachen haben wir in Verwendung mit:

echo DB::num_connections;

Da $ num_connections statisch ist (gemeinsam), wird die Gesamtzahl der aktiven Datenbankobjekte reflektieren. Sie können diese Technik gesehen haben verwendet Datenbankverbindungen unter allen Instanzen einer Datenbank-Klasse zu teilen. Dies geschieht, weil die Datenbankverbindung zu schaffen eine lange Zeit in Anspruch nimmt, so ist es am besten einfach zu erstellen und teilen (dies ist ein Singleton Pattern genannt).

Statische Methoden (das heißt public static Ansicht :: format_phone_number ($ Ziffern)) ohne erste Instanziierung dieser Objekte verwendet werden (das heißt, sie haben intern nicht auf $ dieses beziehen).

Statische Methode Beispiel:

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, öffentliche statische Funktion prettyName weiß nichts über das Objekt. Es funktioniert nur mit den Parametern, die Sie passieren in, wie eine normale Funktion, die nicht Teil eines Objekts ist. Warum sich die Mühe, dann, wenn wir könnten es nur noch nicht als Teil des Objekts?

  1. Zuerst Funktionen auf Objekte Befestigung hilft Ihnen, die Dinge organisiert, so dass Sie wissen, wo sie zu finden.
  2. Zweitens, es verhindert Konflikte zu benennen. In einem großen Projekt, sind Sie wahrscheinlich zwei Entwickler getName () Funktionen haben, erstellen. Wenn man einen Classname 1 :: getName () erzeugt, und die andere schaffen ClassName2 :: getName (), dann ist es überhaupt kein Problem. Kein Konflikt. Yay statische Methoden!

SELF :: Wenn Sie Codierung außerhalb das Objekt, das die statische Methode, die Sie beziehen möchten muss, müssen Sie es den Namen Ansicht des Objekts unter Verwendung rufen :: format_phone_number ($ phone_number); Wenn Sie Codierung innen das Objekt, das die statische Methode hat Sie verweisen möchten, können Sie entweder verwenden Sie den Namen Ansicht des Objekts :: format_phone_number ($ pn) ODER Sie können Sie mit dem Selbst :: format_phone_number ($ pn) Abkürzung

Das gleiche gilt für statische Variablen: Beispiel: :: templates_path gegen self :: templates_path

Innerhalb der DB-Klasse, wenn wir auf eine statische Methode von einem anderen Objekt verweisen, würden wir den Namen des Objekts verwenden: Beispiel: Session :: getUsersOnline ();

Aber wenn die DB-Klasse seine eigene statische Variable verweisen wollte, wäre es nur selbst sagen: Beispiel: self :: Verbindung;

Hope, die klare Dinge hilft:)

dieses Blog-Post :

  
      
  • self bezieht sich auf die aktuelle Klasse
  •   
  • self verwendet werden kann statische Funktionen aufrufen und Referenz statische Membervariablen
  •   
  • self kann innerhalb statischen Funktionen verwendet werden
  •   
  • self kann auch polymorphe Verhalten unter Umgehung des VTable deaktivieren
  •   
  • $this bezieht sich auf das aktuelle Objekt
  •   
  • $this kann verwendet werden, um statische Funktionen aufzurufen
  •   
  • $this sollte nicht verwendet werden, um statische Membervariablen zu nennen. Verwenden Sie self statt.
  •   
  • $this kann nicht in statischen Funktionen verwendet werden
  •   

In PHP, verwenden Sie das selbst Schlüsselwort statische Eigenschaften und Methoden zugreifen zu können.

Das Problem ist, dass Sie $this->method() mit self::method()anywhere ersetzen können, unabhängig davon, ob method() statisch deklariert wird oder nicht. So was sollte man verwenden?

Betrachten Sie diesen Code ein:

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 ausgegeben ‚Eltern‘, während $this->who() wird davon abhängen, welche Klasse das Objekt hat.

Jetzt können wir selbst sehen, auf die Klasse bezieht, in der sie genannt wird, während $this auf die Klasse des aktuellen Objekts verweist .

Also, sollten Sie sich selbst nur verwenden, wenn $this nicht verfügbar ist, oder wenn Sie nicht wollen, abgeleiteten Klassen zu ermöglichen, die aktuelle Methode zu überschreiben.

Innerhalb einer Klassendefinition, $ Dies bezieht sich auf das aktuelle Objekt, während sich auf die aktuelle Klasse bezieht.

Es ist notwendig, zu einem Klasse-Elemente verweisen selbst verwendet und beziehen sich auf ein Objekt Element diesen mit $.

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 dieses und selbst für nicht-statischen $   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();
?> 

Nach http://www.php.net/manual /en/language.oop5.static.php kein $self ist. Es gibt nur $this, für die sich auf die aktuelle Instanz der Klasse (das Objekt), und selbst, die dazu verwendet werden können, um statische Elemente einer Klasse zu verweisen. Der Unterschied zwischen einer Objektinstanz und einer Klasse kommt hier ins Spiel.

self bezieht sich aktuelle Klasse (in der sie genannt wird),

$this bezieht sie aktuelles Objekt. Sie können statt Selbst statisch verwenden. Siehe 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:       Elternteil      Kind

  • Der Objektzeiger $ this auf das aktuelle Objekt verweist.
  • Der Klassenwert „statisch“ bezieht sich auf das aktuelle Objekt.
  • Der Klassenwert „Selbst“ bezieht sich auf die genaue Klasse es in definiert wurde.
  • Der Klassenwert „Eltern“ bezieht sich auf die Eltern der genauen Klasse es in definiert wurde.

Siehe das folgende Beispiel dafür, zu überlasten.

<?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"

Die meisten der Zeit, die Sie auf die aktuelle Klasse beziehen möchten, weshalb Sie static oder $this verwenden. Es gibt jedoch Zeiten, in denen Sie Notwendigkeit self, weil Sie die ursprüngliche Klasse unabhängig davon wollen, was es erstreckt. (Sehr, sehr selten)

Da niemand hier über Aufführungen gesprochen, hier ist ein kleiner Maßstab Ich 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äuft, und hier ist der Code, den ich verwendet:

<?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();

Ich glaube Frage war nicht, ob Sie durch den Aufruf ClassName::staticMember das statische Element der Klasse aufrufen können. Frage war, was ist der Unterschied zwischen der Verwendung von self::classmember und $this->classmember.

Für beispielsweise die beiden folgenden Beispiele funktionieren ohne Fehler, ob Sie verwenden self:: oder $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;
    }
}

Wenn self mit dem :: Operator verwendet wird, bezieht sich auf die aktuelle Klasse, die sowohl in statischen und nicht statischen Kontexten durchgeführt werden kann. $this bezieht sich auf das Objekt selbst. Darüber hinaus ist es vollkommen legal $this zu verwenden statische Methoden zu nennen (aber nicht beschränkt auf Felder beziehen).

$this bezieht sich auf die aktuelle Klasse-Objekt verweist self auf die aktuelle Klasse (nicht Objekt). Die Klasse ist der Bauplan des Objekts. So haben Sie eine Klasse definieren, aber Sie Objekte konstruieren.

Also mit anderen Worten, verwendet self for static und this for none-static members or methods.

auch in Kind / Eltern Szenario self / parent ist vor allem auf identifizierte Kind und Eltern-Klasse Mitglieder und Methoden verwendet.

Zusätzlich da hat $this:: noch nicht diskutiert worden.

Nur zu Informationszwecken, wie von PHP 5.3, wenn sie mit instanzierte Objekten Umgang den aktuellen Umfang Wert zu erhalten, im Gegensatz zur Verwendung static::, kann man alternativ wie so verwendet $this::.

http://ideone.com/7etRHy

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

über den Code zu verwenden ist nicht üblich oder Praxis empfohlen, ist aber einfach seine Verwendung zu veranschaulichen, und ist eher als handeln „Wissen Sie schon?“ in Bezug auf die Frage der Original-Poster.

Es stellt auch die Verwendung von $object::CONSTANT zum Beispiel echo $foo::NAME; im Gegensatz zu $this::NAME;

Ich lief in die gleiche Frage und die Antwort ist ganz einfach:

  • $ this eine Instanz der Klasse erfordert
  • self :: nicht

Wenn Sie mit statische Methoden oder statische Attribute und sie nennen wollen, ohne ein Objekt der Klasse, die instanziiert Sie selbst verwenden müssen :: , um sie zu nennen, weil $ this auf Objekt erfordert immer erstellt werden.

Verwenden Sie self, wenn Sie eine Methode einer Klasse aufrufen wollen, ohne ein Objekt / Instanz dieser Klasse zu schaffen, das spart RAM (manchmal selbst für diesen Zweck verwendet werden). Mit anderen Worten, ruft es tatsächlich eine Methode statisch. Verwenden Sie this für Objekt Perspektive.

Fall 1: Verwenden Sie self können für Klassenkonstanten verwendet werden

 class classA { 
     const FIXED_NUMBER = 4; 
     self::POUNDS_TO_KILOGRAMS
}

Wenn Sie es nennen wollen außerhalb der Klasse, verwenden classA::POUNDS_TO_KILOGRAMS die Konstanten zugreifen

Fall 2: Bei statischen Eigenschaften

class classC {
     public function __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 den Zugriff auf Eigenschaften oder Methoden von innerhalb der Klassendefinition.

$this, auf der anderen Seite, wird verwendet, so lange eine Instanz und Methoden einer Klasse zu nennen, wie die Klasse zugänglich ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top