2010-02-04 24 views
111

Wie rufe ich eine statische Methode von einer anderen Methode innerhalb der gleichen Klasse?eine statische Methode in einer Klasse aufrufen?

$this->staticMethod(); 

oder

$this::staticMethod(); 
+11

Sie könnten daran interessiert sein ('self' vs.' $ this') : http://stackoverflow.com/questions/151969/php-self-vs-this –

+0

Nur ein FYI, Ihr erstes Beispiel ist eine Instanzvariable, die eine statische Methode aufruft, die nicht möglich ist, weil eine statische Methode Teil der Klasse ist und ist nicht über eine Instanzvariable zugänglich. – joejoeson

+0

Sie können das $ this jetzt bitte löschen, es funktioniert nicht, wenn nur statische Methoden verwendet werden und keine Instanz existiert. – malhal

Antwort

211
+0

... aber warum? $ this-> staticMethod() funktioniert auch. Kannst du erklären, warum self :: staticMethod() korrekter ist (wenn es ist)? –

+15

@Ian Dunn Einfach ausgedrückt, '$ this' existiert nur, wenn ein Objekt instanziiert wurde und Sie können' $ this-> method' nur innerhalb eines bestehenden Objekts verwenden. Wenn Sie kein Objekt haben, sondern nur eine statische Methode aufrufen und in dieser Methode eine andere statische Methode in derselben Klasse aufrufen wollen, müssen Sie 'self ::' verwenden. Um mögliche Fehler (und strenge Warnungen) zu vermeiden, ist es besser, 'self' zu verwenden. – jeroen

+0

Sie können $ this nicht in einer statischen Funktion verwenden .... – patrick

36

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"; } 
} 

Aus dem foo() Methode, schauen wir uns die verschiedenen Optionen aussehen:

$this->staticMethod(); 

So dass als Instanzmethode aufruft, richtig? Es tut nicht. Dies liegt daran, dass die Methode als public static deklariert ist. Der Interpreter wird sie als statische Methode bezeichnen, so dass sie wie erwartet funktioniert. Es könnte argumentiert werden, dass es aus dem Code, dass ein statischer Methodenaufruf stattfindet, weniger offensichtlich wird.

$this::staticMethod(); 

Seit 5.3 PHP können Sie $var::method()<class-of-$var>:: bedeuten verwenden; das ist sehr praktisch, obwohl der obige Anwendungsfall immer noch ziemlich unkonventionell ist. Also das bringt uns auf die gängigste Methode, eine statische Methode des Aufrufs:

self::staticMethod(); 

Nun, bevor Sie anfangen zu denken, dass die :: ist der statische Aufruf Operator, lassen Sie mich Ihnen ein anderes Beispiel:

self::bar(); 

Dies wird baz = 1 drucken, was bedeutet, dass $this->bar() und self::bar() genau dasselbe tun; Das liegt daran, dass :: nur ein Scope-Resolution-Operator ist. Es ist da, um parent::, self:: und static:: arbeiten zu lassen und Ihnen Zugang zu statischen Variablen zu geben; Wie eine Methode aufgerufen wird, hängt von ihrer Signatur und dem Aufruf des Aufrufers ab.

Um alles in Aktion zu sehen, siehe this 3v4l.org output.

+6

+1 für die Erklärung – FreshPro

+0

'self :: bar()' scheint irreführend - ist das jetzt veraltet? (Verwenden von 'self ::', um eine Instanzmethode anstelle einer statischen Methode aufzurufen). – ToolmakerSteve

+0

@ToolmakerSteve Wie würden Sie sagen, dass es irreführend ist? –

7

Dies ist eine sehr späte Antwort, aber die vorherigen zwei Antworten sind ein bisschen irreführend.

Wenn es darum geht, statische Methoden in PHP von einer anderen statischen Methode in derselben Klasse aufzurufen, ist es wichtig, zwischen self und dem Klassennamen zu unterscheiden.

Nehmen wir 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); 

Der Ausgang dieses Codes ist:

Original-Klasse

Erweiterte Klasse

Dies liegt daran, self bezieht sich auf die Klasse, in der sich der Code befindet, und nicht die c Mädchen des Codes, aus dem es aufgerufen wird.

Wenn Sie eine Methode für eine Klasse definiert verwenden möchten, die die ursprüngliche Klasse erbt, müssen Sie etwas verwenden wie:

$class = get_called_class(); 
$class::function_name(); 
+2

Ich fand das informativ. Eine kleine Nisse, ich würde nicht sagen, dass die anderen Antworten "irreführend" sind. Genauer gesagt, sie sind "unvollständig"; Sie behandeln nicht die (nicht gestellte) Frage, was "self ::" in dem (seltenen) Fall tut, in dem eine statische Methode A eine andere statische Methode B aufruft und B in einer Unterklasse überschrieben wurde. IMHO, es ist weniger verwirrend, die Methode auf "Instanz" -Methoden zu überschreiben; verwende diese Fähigkeit sparsam auf der statischen Ebene. Anders gesagt, die Leser Ihres Codes erwarten, dass die Methodenmethode überschrieben wird (das ist die Essenz der OO-Codierung), nicht jedoch die der statischen Methoden. – ToolmakerSteve

+1

Sehr hilfreich und es macht Sinn, dass eine Erweiterung der Klasse nicht die ursprüngliche Klasse ist. Daher liegt es nahe, dass "Selbst" in diesem Fall nicht verwendet wird. Sie haben eine separate Klasse als Erweiterung der ersten Klasse deklariert. Die Verwendung von "self" innerhalb der erweiterten Klasse würde sich auf die erweiterte Klasse beziehen. Dies steht nicht im Widerspruch zu den anderen Antworten, aber es hilft sicherlich, den Bereich des "Selbst" zu demonstrieren. – iyrin

1

In der späteren PHP Version self::staticMethod(); auch wird nicht funktionieren. Es wird den strengen Standardfehler werfen.

In diesem Fall können wir Objekt derselben Klasse erstellen und rufen Sie durch das Objekt

hier ist das Beispiel

class Foo { 

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

    public static function fun2() { 
     echo (new self)->fun1(); 
    } 
} 
+0

Großer Eingang, danke – Joundill

Verwandte Themen