Menu
Coddy logo textTech

__call & __callStatic

Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy. Lektion 47 von 91.

So wie __get() und __set() den Zugriff auf Eigenschaften abfangen, fangen die Methoden __call() und __callStatic() Methodenaufrufe ab. Sie werden ausgelöst, wenn du eine Methode aufrufst, die für ein Objekt oder eine Klasse nicht existiert oder nicht zugänglich ist.

Die Methode __call() verarbeitet Aufrufe von Instanzmethoden. 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, World

Für Aufrufe statischer Methoden verwende __callStatic(). Beachte, dass sie 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.com

Diese magischen Methoden sind leistungsstark zum Erstellen flüssiger APIs, zum Implementieren der Methodenweiterleitung oder zum Aufbau dynamischer Abfrage-Builder, bei denen Methodennamen in Datenbankoperationen übersetzt werden. Sie ermöglichen es deinen Objekten, intelligent auf jeden Methodenaufruf zu reagieren, selbst auf solche, die du nicht ausdrücklich definiert hast.

challenge icon

Aufgabe

Einfach

Erstellen wir einen dynamischen API-Client, der magische Methoden verwendet, um Methodenaufrufe flexibel zu verarbeiten. Du erstellst eine Klasse, die sowohl Instanz- als auch statische Methodenaufrufe abfängt und sie in aussagekräftige API-ähnliche Antworten umwandelt, ohne jede Methode ausdrücklich zu definieren.

Du organisierst deinen Code auf zwei Dateien verteilt:

  • ApiClient.php: Erstelle eine ApiClient-Klasse, die API-Interaktionen mithilfe magischer Methoden simuliert. Deine Klasse sollte eine private Eigenschaft $baseUrl besitzen, die über den Konstruktor festgelegt wird. Implementiere zwei magische Methoden:
    • __call(): Verarbeitet Aufrufe von Instanzmethoden. Wenn eine Methode aufgerufen wird, die mit get beginnt (zum Beispiel getUsers oder getPosts), extrahiere den Ressourcennamen (den Teil nach „get“) und gib "GET [baseUrl]/[resource]: [arguments joined by comma]" zurück. Der Ressourcenname sollte in Kleinbuchstaben umgewandelt werden. Wenn die Methode nicht mit „get“ beginnt, gib "Unknown action: [methodName]" zurück.
    • __callStatic(): Verarbeitet Aufrufe statischer Methoden. Wenn eine Methode aufgerufen wird, die mit create beginnt (zum Beispiel createUser), extrahiere den Ressourcennamen und gib "POST /[resource]: [arguments joined by comma]" zurück. Der Ressourcenname sollte in Kleinbuchstaben geschrieben werden. Für Methoden, die mit delete beginnen, gib "DELETE /[resource]: [first argument]" zurück. Für jede andere Methode gib "Static action not supported: [methodName]" zurück.
  • main.php: Binde die ApiClient-Datei ein. Du erhältst drei Eingaben: eine Basis-URL, einen Ressourcenbezeichner und einen Wert. Erstelle eine ApiClient-Instanz mit der Basis-URL. Gib anschließend vier Zeilen aus:
    • Rufe eine dynamische get-Methode auf, wobei der Ressourcenbezeichner als Suffix des Methodennamens verwendet wird (wenn die Ressource beispielsweise „Users“ lautet, rufe getUsers auf), und übergib den Wert als Argument.
    • Rufe getProducts mit zwei Argumenten auf: "electronics" und "active".
    • Rufe die statische Methode createOrder mit dem Wert als Argument auf.
    • Rufe die statische Methode deleteItem mit dem Ressourcenbezeichner als Argument auf.

Die magischen Methoden ermöglichen es deinem API-Client, dynamisch auf jeden Methodenaufruf zu reagieren. Anstatt getUsers(), getPosts(), getProducts() und Dutzende weitere Methoden zu definieren, verarbeitet eine einzige Methode __call() sie alle, indem sie den Methodennamen untersucht und die relevanten Informationen extrahiert.

Probier es selbst

<?php

require_once 'ApiClient.php';

// Eingaben lesen
$baseUrl = trim(fgets(STDIN));
$resource = trim(fgets(STDIN));
$value = trim(fgets(STDIN));

// TODO: Erstelle eine ApiClient-Instanz mit der Basis-URL

// TODO: Rufe eine dynamische get-Methode auf und verwende die resource als Suffix des Methodennamens
// Hinweis: Verwende variable Methodenaufrufe wie $api->{"get" . $resource}($value)

// TODO: Rufe getProducts mit zwei Argumenten auf: "electronics" und "active"

// TODO: Rufe die statische Methode createOrder mit dem value als Argument auf
// Hinweis: Verwende ApiClient::createOrder($value)

// TODO: Rufe die statische Methode deleteItem mit der resource als Argument auf

?>
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-PHP-Compiler