2016-04-03 7 views
2

Es ist ziemlich schwierig, mit einem Titel für diese Frage zu kommen, aber im Grunde ist hier der Code:Warum genau führt die Übergabe einer Schließung von einer Klasse zur anderen und den Aufruf von der zweiten Klasse Code aus der ersten Klasse ausführen?

<?php 

class Sub { 
    protected $closure; 

    public function setClosure($closure) { 
     $this->closure = $closure; 
    } 

    public function callClosure() { 
     $this->closure->__invoke(); 
    } 

    protected function outcome() { 
     echo 'calling from sub'; 
    } 
} 

class Main { 
    public function __construct() { 
     $this->sub = new Sub(); 
    } 

    public function start() { 
     $this->sub->setClosure(function() { 
      $this->outcome(); 
     }); 

     $this->sub->callClosure(); 
    } 

    protected function outcome() { 
     echo 'calling from main'; 
    } 
} 

$main = new Main(); 
$main->start(); 

Das Ergebnis davon ist calling from main. Das ist genau das, was ich will, da ich mich mit diesem Verhalten beschäftigen werde und ich verstehe nicht ganz, warum es so funktioniert, möchte ich etwas Klärung.

Bevor ich den Code schrieb, erwartete ich, dass er die outcome-Methode aus der Klasse Sub, nicht aus der Klasse Main aufruft. Verwendet der Abschluss $this aus dem Bereich, aus dem es definiert wurde? Was ist, wenn ich, aus welchem ​​Grund auch immer, möchte ich $this aus dem Bereich verwenden, aus dem es aufgerufen wird?

+3

Da der Schließung werden [in die zweite Klasse Instanz gebunden] muss (http://php.net/manual/en/closure.bind.php) –

Antwort

1

Es funktioniert einwandfrei und nach php anonymous functions Handbuch weil

Der übergeordnete Rahmen eines Verschlusses ist die Funktion, bei der der Verschluss wurde erklärt (nicht unbedingt die Funktion aus aufgerufen wurde)

In php sind diese anonymen Funktionen implementiert als Closure class. Und wie schon Mark Baker gesagt, wenn Sie Ihre Schließung innerhalb Ihrer Main Klasse erstellen, erhalten Sie automatisch dieses gebundene Objekt und diesen Klassenbereich.

Der „gebundene Objekt“ bestimmt der Wert $ this in der Funktion Körper haben und die „Klassenbereich“ steht für eine Klasse, die welche Mitglieder die anonyme Funktion private und geschützte bestimmt der Lage sein wird, zuzugreifen. Die Elemente, die sichtbar sein werden, sind nämlich genauso, als ob die anonyme Funktion eine Methode der angegebenen Klasse als Wert des newscope-Parameters wäre.

In Ihrem Fall ist diese Klasse Main nicht Sub