2009-07-24 12 views
4

Ist es möglich, über eine Kette von Methodenaufrufen nachzudenken, um festzustellen, an welchem ​​Punkt Sie sich in der Anrufkette befinden? Zumindest ist es möglich zu unterscheiden, ob eine Methode der letzte Aufruf in der Kette ist?PHP-Methodenketten - Reflektieren?

$instance->method1()->method2()->method3()->method4() 

Ist es möglich, dieselben Eigenschaften zu verwenden, die Instanzen von Objekten zurückgeben?

$instances->property1->property2->property3->property4 
+1

Aus Interesse, könnten Sie erklären, warum Sie das tun möchten? Es scheint ein wenig merkwürdig, dass Sie möchten, dass eine Klasse weiß, wie ihre Methoden extern aufgerufen werden. –

Antwort

0
$instances->property1->property2->property3->property4->method(); 

ODER

$instances->property1->property2->property3->property4=some_value 

Was die erste Frage: nicht ohne einige Code hinzufügen zu verfolgen, wo Sie in der Kette sind.

1

Für verkettete Methoden können Sie PHP5 overloading methods verwenden (in diesem Fall __call).

Ich sehe keinen Grund, warum Sie verkettete Eigenschaften verfolgen möchten. Wenn Sie jedoch darauf bestehen, können Sie die __get-Überlademethode für Ihre Klassen verwenden, um die gewünschte Funktionalität hinzuzufügen.

Bitte lassen Sie mich wissen, wenn Sie nicht herausfinden konnten, wie Sie die obigen Vorschläge verwenden.

+0

Dies scheint der bisher beste Ansatz zu sein, allerdings sehe ich immer noch nicht, warum jemand die Position einer verketteten Methode/eines Eigenschaftsaufrufs verfolgen möchte. –

1

debug_backtrace() wird nicht korrekt sein in Bezug auf die Verwendung von "fließenden Schnittstellen" (der richtige Name für die "Verkettung" dargestellt), weil jede Methode zurückgibt, bevor der nächste aufgerufen wird.

+1

Sie haben Recht. Die Antwort wurde korrigiert. Vielen Dank, dass Sie darauf hingewiesen haben. –

0

Ich glaube nicht, dass es eine praktikable Möglichkeit für eine Klasse gibt zu wissen, wann der letzte Methodenaufruf gemacht wurde. Ich denke du brauchst eine Art von -> execute(); Funktionsaufruf am Ende der Kette.

Darüber hinaus würde die Aktivierung solcher Funktionalität meiner Meinung nach den Code wahrscheinlich zu magisch machen und Benutzer überraschen und/oder fehlerhafte Symptome haben.

+0

Das ist etwas meine Absicht an diesem Punkt. Schreiben Sie ein ORM, Magie ist definitiv auf der Speisekarte! –

2

Wenn alle aufgerufenen Methoden das selbe Objekt zurückgeben, um die fließende Schnittstelle zu erstellen (im Gegensatz zur Verkettung verschiedener Objekte), sollte es ziemlich trivial sein, die Methodenaufrufe im Objekt selbst aufzuzeichnen.

zB:

class Eg { 
    protected $_callStack = array(); 

    public function f1() 
    { 
     $this->_callStack[] = __METHOD__; 
     // other work 
    } 

    public function f2() 
    { 
     $this->_callStack[] = __METHOD__; 
     // other work 
    } 

    public function getCallStack() 
    { 
     return $this->_callStack; 
    } 
} 

Dann Verkettungs die Anrufe wie

$a = new Eg; 
$a->f1()->f2()->f1(); 

würde den Anruf Stapel wie verlassen: -Array ('F1', 'F2', 'f1');

+0

Dies ist ein Ansatz, den ich in Betracht gezogen habe, obwohl er einige der Daten von den zurückgegebenen Objekten wegbewegt, so dass sie nicht ganz so zusammenhängend sind. Das Hauptproblem bleibt, dass ich immer noch nicht feststellen kann, wann ich am Ende einer Kette bin.So bin ich stecken geblieben mit etwas wie: "$ a-> f1() -> f2() -> f1() -> go();" um das Ende einer Kette auszulösen. –

+1

Richtig, ich glaube nicht, dass es eine Möglichkeit geben wird, das "Ende der Kette" automatisch zu erkennen. Wenn Sie versuchen, eine SQL-Abfrage zu erstellen (was bei den anderen Kommentaren meine beste Vermutung ist), dann könnte die Implementierung der __toString-magischen Methode in der Klasse den Aufruf-Stack betrachten und die endgültige SQL-Zeichenfolge erzeugen. So sind viele View-Helfer im Zend Framework implementiert. So tun Echo $ a-> f1() -> f2() -> f1(); (oder irgendeine andere Funktion, die bewirkt, dass eine Kaste zu einer Zeichenkette wird), würde implizit die __toString() -Methode aufrufen und die Arbeit Ihrer go() -Methode erledigen. –

Verwandte Themen