Kürzlich habe ich das Buch „php Core Technology and Best Practices“ gelesen. Im ersten Kapitel des Buches wird erwähnt, dass die __call()-Methode zum Implementieren einer einfachen Zeichenfolgenkettenoperation verwendet werden kann dann Die Operation zum Ermitteln der Länge wird im Allgemeinen wie folgt geschrieben:
strlen(trim($str));
Kann also die folgende Schreibweise erreicht werden?
$str->trim()->strlen();
Versuchen wir es unten.
Kettenoperation ist, um es klar auszudrücken, eigentlich eine Kettenmethode zum Aufrufen von Objektmethoden. Da Sie String-Kettenoperationen implementieren möchten, müssen Sie eine String-Klasse implementieren und dann das Objekt dieser Klasse aufrufen. Meine Erwartungen an die String-Klasse sind wie folgt: (1) Wenn ich das Objekt erstelle, kann ich den String einer Eigenschaft des Objekts zuweisen und auf diese Eigenschaft zugreifen, um den Wert zu lesen. (2) Ich kann trim( aufrufen; ) und strlen( )-Methode; (3) Ich kann die Methode $str->trim()->strlen() auch so aufrufen.
Punkt (1) oben ist die Grundvoraussetzung für eine String-Klasse. Implementieren Sie dies zuerst:
class String { public $value; public function __construct($str=null) { $this->value = $str; } }
Sie können Folgendes versuchen:
1 $str = new String('01389');
2 echo $str->
Dann schauen Sie sich Punkt 2 an, implementieren Sie zuerst $str->trim(), beziehen Sie sich auf die Idee im Buch: Lösen Sie die __call-Methode aus und führen Sie dann call_user_func aus . Der Code lautet wie folgt:
class String { public $value; public function __construct($str=null) { $this->value = $str; } public function __call($name, $args) { $this->value = call_user_func($name, $this->value, $args[0]); return $this; } }
Test:
1 $str = new String('01389');
2 echo $str->trim( '0 ')->value;
Das Ergebnis ist wie folgt:
Was oben beachtet werden muss, ist Zeile 12: $ this->value = call_user_func($name, $this->value, $args[0]); $name ist der Name der Callback-Funktion (hier ist trim), die letzten beiden sind die Parameter der Callback-Funktion (tirm), ändern Sie die Reihenfolge der Parameter nicht auf den Kopf. $args ist ein Array, Sie müssen also aufpassen.
Strlen() muss in Artikel 2 implementiert werden. Zu diesem Zeitpunkt ist Zeile 13 im obigen Code sehr wichtig: return $this; Seine Funktion besteht darin, trim() in Zeile 12 aufzurufen, um die Verarbeitung abzuschließen Nach der Zeichenfolge wird das Wertattribut neu zugewiesen und dann die Referenz des aktuellen Objekts zurückgegeben, sodass andere Methoden im Objekt kontinuierliche Operationen für den Attributwert ausführen und so Kettenoperationen realisieren können. $str->strlen() wird wie folgt implementiert:
class String { public $value; public function __construct($str=null) { $this->value = $str; } public function __call($name, $args) { $this->value = call_user_func($name, $this->value, $args[0]); return $this; } public function strlen() { return strlen($this->value); } }
Test:
1 $str = new String('01389');
2 echo $ str->strlen();
Ergebnis:
Kettenoperation:
echo $str-> trim('0')->strlen();
Ergebnis:
class String { public $value; public function __construct($str=null) { $this->value = $str; } public function trim($t) { $this->value = trim($this->value, $t); return $this; } public function strlen() { return strlen($this->value); } }
Der Schlüssel zur Kettenoperation liegt darin, etwas zu tun Geben Sie $this nach Abschluss des Vorgangs zurück.
Darüber hinaus ist dieser Artikel von diesem Artikel im Garten inspiriert, indem er die Implementierung von call_user_func() durch call_user_func_array() ersetzt und die Methode __call() wie folgt ändert.
public function __call($name, $args) { array_unshift($args, $this->value); $this->value = call_user_func_array($name, $args); return $this; }
hat den gleichen Effekt wie die obige __call()-Methode, sodass der Code eleganter erscheint als die vorherige Implementierung.
Zusammenfassung:
__call() wird ausgelöst, wenn das Objekt eine unzugängliche Methode aufruft, sodass es die Erstellung dynamischer Methoden der Klasse und die Methodenüberladungsfunktion von PHP realisieren kann es Tatsächlich handelt es sich um einen syntaktischen Zucker (auch die __construct()-Methode).
Kann also die Erstellung dynamischer Methoden und Kettenoperationen realisiert werden, wenn es keinen Syntaxzucker wie __call() gibt? Ich denke, es wird folgende Aspekte beinhalten: ob die Klassenmethode existiert und aufgerufen werden kann. Dies kann mithilfe von method_exists, is_callable, get_class_methods und anderen Methoden erreicht werden. Darüber hinaus wird den Attributen beim Erstellen eines Objekts ein Wert zugewiesen syntaktischer Zucker. Praktisch, aber nicht notwendig. Lasst es uns noch einmal studieren, wenn wir Zeit haben.