eine statische Methode innerhalb einer Klasse aufrufen?

166

Wie rufe ich eine statische Methode von einer anderen Methode innerhalb derselben Klasse auf?

$this->staticMethod();

oder

$this::staticMethod();
Ajsie
quelle
13
Das könnte Sie interessieren ( selfvs. $this): stackoverflow.com/questions/151969/php-self-vs-this
Felix Kling
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.
Malhal

Antworten:

321
self::staticMethod();

Weitere Informationen zum Schlüsselwort Static.

Jeroen
quelle
...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::
Seien Sie
44

Nehmen wir an, dies ist Ihre Klasse:

class Test
{
    private $baz = 1;

    public function foo() { ... }

    public function bar() 
    {
        printf("baz = %d\n", $this->baz);
    }

    public static function staticMethod() { echo "static method\n"; }
}

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.

Um all dies in Aktion zu sehen, sehen Sie sich diese 3v4l.org-Ausgabe an .

Jack
quelle
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 .

Nehmen Sie zum Beispiel diesen Code:

class static_test_class {
    public static function test() {
        echo "Original class\n";
    }

    public static function run($use_self) {
        if($use_self) {
            self::test();
        } else {
            $class = get_called_class();
            $class::test(); 
        }
    }
}

class extended_static_test_class extends static_test_class {
    public static function test() {
        echo "Extended class\n";
    }
}

extended_static_test_class::run(true);
extended_static_test_class::run(false);

Die Ausgabe dieses Codes lautet:

Ursprüngliche Klasse

Erweiterte Klasse

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:

$class = get_called_class();
$class::function_name(); 
Joundill
quelle
2
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

Hier ist das Beispiel

class Foo {

    public function fun1() {
        echo 'non-static';   
    }

    public static function fun2() {
        echo (new self)->fun1();
    }
}
Nishad Up
quelle
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.
ToolmakerSteve