__call & __callStatic
Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy — Lektion 47 von 91.
Genauso wie __get() und __set() den Zugriff auf Eigenschaften abfangen, fangen die Methoden __call() und __callStatic() Methodenaufrufe ab. Sie werden ausgelöst, wenn Sie eine Methode aufrufen, die nicht existiert oder auf die in einem Objekt oder einer Klasse nicht zugegriffen werden kann.
Die __call()-Methode verarbeitet Instanzmethodenaufrufe. Sie erhält den Methodennamen und ein Array von Argumenten:
<?php
class Messenger {
public function __call(string $name, array $arguments): string {
return "Called '$name' with: " . implode(", ", $arguments);
}
}
$msg = new Messenger();
echo $msg->sendEmail("Hello", "World");
Ausgabe:
Called 'sendEmail' with: Hello, WorldFür statische Methodenaufrufe verwenden Sie __callStatic(). Beachten Sie, dass es als static deklariert werden muss:
<?php
class QueryBuilder {
public static function __callStatic(string $name, array $arguments): string {
if (str_starts_with($name, "findBy")) {
$field = substr($name, 6);
return "Finding by $field: " . $arguments[0];
}
return "Unknown method: $name";
}
}
echo QueryBuilder::findByEmail("test@example.com");
Ausgabe:
Finding by Email: test@example.comDiese magischen Methoden sind leistungsstark für die Erstellung von Fluent APIs, die Implementierung von Method Forwarding oder den Aufbau dynamischer Query Builder, bei denen Methodennamen in Datenbankoperationen übersetzt werden. Sie ermöglichen es Ihren Objekten, intelligent auf jeden Methodenaufruf zu reagieren, selbst auf solche, die Sie nicht explizit definiert haben.
Aufgabe
EinfachLassen Sie uns einen dynamischen API-Client erstellen, der magische Methoden verwendet, um Methodenaufrufe flexibel zu handhaben. Sie werden eine Klasse erstellen, die sowohl Instanz- als auch statische Methodenaufrufe abfängt und diese in aussagekräftige API-ähnliche Antworten übersetzt, ohne jede Methode explizit zu definieren.
Sie werden Ihren Code in zwei Dateien organisieren:
ApiClient.php— Erstellen Sie eineApiClient-Klasse, die API-Interaktionen mithilfe magischer Methoden simuliert. Ihre Klasse sollte eine private$baseUrl-Eigenschaft haben, die über den Konstruktor gesetzt wird. Implementieren Sie zwei magische Methoden:__call()— Verarbeitet Instanzmethodenaufrufe. Wenn eine Methode aufgerufen wird, die mitgetbeginnt (wiegetUsersodergetPosts), extrahieren Sie den Ressourcennamen (den Teil nach "get") und geben Sie"GET [baseUrl]/[resource]: [arguments joined by comma]"zurück. Der Ressourcenname sollte in Kleinbuchstaben umgewandelt werden. Wenn die Methode nicht mit "get" beginnt, geben Sie"Unknown action: [methodName]"zurück.__callStatic()— Verarbeitet statische Methodenaufrufe. Wenn eine Methode aufgerufen wird, die mitcreatebeginnt (wiecreateUser), extrahieren Sie den Ressourcennamen und geben Sie"POST /[resource]: [arguments joined by comma]"zurück. Der Ressourcenname sollte kleingeschrieben sein. Für Methoden, die mitdeletebeginnen, geben Sie"DELETE /[resource]: [first argument]"zurück. Für jede andere Methode geben Sie"Static action not supported: [methodName]"zurück.
main.php— Binden Sie die ApiClient-Datei ein. Sie erhalten drei Eingaben: eine Basis-URL, einen Ressourcen-Identifikator und einen Wert. Erstellen Sie eineApiClient-Instanz mit der Basis-URL. Geben Sie dann vier Zeilen aus:- Rufen Sie eine dynamische
get-Methode auf, wobei der Ressourcen-Identifikator als Suffix des Methodennamens verwendet wird (z. B. wenn die Ressource "Users" ist, rufen SiegetUsersauf) mit dem Wert als Argument - Rufen Sie
getProductsmit zwei Argumenten auf:"electronics"und"active" - Rufen Sie die statische Methode
createOrdermit dem Wert als Argument auf - Rufen Sie die statische Methode
deleteItemmit dem Ressourcen-Identifikator als Argument auf
- Rufen Sie eine dynamische
Die magischen Methoden ermöglichen es Ihrem API-Client, dynamisch auf jeden Methodenaufruf zu reagieren. Anstatt getUsers(), getPosts(), getProducts() und Dutzende weitere zu definieren, verarbeitet eine einzige __call()-Methode sie alle, indem sie den Methodennamen untersucht und die relevanten Informationen extrahiert.
Spickzettel
Die Methode __call() fängt Aufrufe von Instanzmethoden ab, die nicht existieren oder nicht zugänglich sind. Sie erhält den Methodennamen und ein Array mit Argumenten:
<?php
class Messenger {
public function __call(string $name, array $arguments): string {
return "Called '$name' with: " . implode(", ", $arguments);
}
}
$msg = new Messenger();
echo $msg->sendEmail("Hello", "World");
// Ausgabe: Called 'sendEmail' with: Hello, World
Die Methode __callStatic() fängt statische Methodenaufrufe ab. Sie muss als static deklariert werden:
<?php
class QueryBuilder {
public static function __callStatic(string $name, array $arguments): string {
if (str_starts_with($name, "findBy")) {
$field = substr($name, 6);
return "Finding by $field: " . $arguments[0];
}
return "Unknown method: $name";
}
}
echo QueryBuilder::findByEmail("test@example.com");
// Ausgabe: Finding by Email: test@example.com
Diese magischen Methoden sind nützlich für die Erstellung von Fluent APIs, die Implementierung von Methodenweiterleitungen oder den Aufbau dynamischer Query-Builder, bei denen Methodennamen in Operationen übersetzt werden.
Probier es selbst
<?php
require_once 'ApiClient.php';
// Eingaben lesen
$baseUrl = trim(fgets(STDIN));
$resource = trim(fgets(STDIN));
$value = trim(fgets(STDIN));
// TODO: Erstellen Sie eine ApiClient-Instanz mit der Basis-URL
// TODO: Rufen Sie eine dynamische get-Methode auf, wobei die Ressource als Suffix des Methodennamens verwendet wird
// Hinweis: Verwenden Sie variable Methodenaufrufe wie $api->{"get" . $resource}($value)
// TODO: Rufen Sie getProducts mit zwei Argumenten auf: "electronics" und "active"
// TODO: Rufen Sie die statische Methode createOrder mit dem Wert als Argument auf
// Hinweis: Verwenden Sie ApiClient::createOrder($value)
// TODO: Rufen Sie die statische Methode deleteItem mit der Ressource als Argument auf
?>Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas $this-SchlüsselwortMethodenEigenschaftenKonstruktor (__construct)Destruktor (__destruct)Rückblick - Einfacher Taschenrechner4Vererbung
Grundlagen der VererbungDas parent:: SchlüsselwortMethoden überschreibenDas final SchlüsselwortAbstrakte KlassenZusammenfassung – Mitarbeiter-Hierarchie7Kapselung
Public, Protected, PrivateZugriffsmodifikatoren im DetailGetter und SetterInformation HidingConstructor Promotion (8.0)Zusammenfassung – Studentenverwaltungssystem2Namensräume & Autoloading
Einführung in NamensräumeDas use-SchlüsselwortPSR-4 Autoloading-StandardComposer AutoloaderZusammenfassung – Organisiertes Projekt5Interfaces & Verträge
Einführung in InterfacesInterfaces implementierenMehrfache Interface-ImplementierungInterface vs. Abstrakte KlasseType Hinting mit InterfacesZusammenfassung – Formen-Rechner8Magische Methoden
Einführung in magische Methoden__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Objekt-Klonen__serialize & __unserializeZusammenfassung - Eigene Collection11Typsystem & Fehlerbehandlung
TypdeklarationenNullable-TypenUnion- & Intersection-TypenException-KlassenEigene Exception-HierarchieTry, Catch, FinallyZusammenfassung - Formular-Validator14Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Klasseneigenschaften
Instanz- vs. statische EigenschaftenKonstanten in KlassenStatische Methoden & EigenschaftenPrivate & geschützte EigenschaftenReadonly-Eigenschaften (PHP 8.1)Zusammenfassung – Bankkonto-Manager6Polymorphismus
Method Overriding erneut betrachtetPolymorphismus über InterfacesType Hinting & Union TypesLate Static BindingZusammenfassung – Payment Processor9Traits
Einführung in TraitsVerwendung mehrerer TraitsKonfliktlösung bei TraitsAbstrakte Methoden in TraitsTraits vs. Vererbung12Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster15Abschlussherausforderungen
E-Learning-PlattformBanksystemSpielcharakter-EntwicklungFahrzeugvermietung