Menu
Coddy logo textTech

__call & __callStatic

Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy — leçon 47 sur 91.

Tout comme __get() et __set() interceptent l'accès aux propriétés, les méthodes __call() et __callStatic() interceptent les appels de méthodes. Elles sont déclenchées lorsque vous appelez une méthode qui n'existe pas ou qui est inaccessible sur un objet ou une classe.

La méthode __call() gère les appels de méthodes d'instance. Elle reçoit le nom de la méthode et un tableau d'arguments :

<?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");

Sortie :

Called 'sendEmail' with: Hello, World

Pour les appels de méthodes statiques, utilisez __callStatic(). Notez qu'elle doit être déclarée comme static :

<?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");

Sortie :

Finding by Email: test@example.com

Ces méthodes magiques sont puissantes pour créer des API fluides, implémenter le transfert de méthodes ou construire des générateurs de requêtes dynamiques où les noms de méthodes se traduisent en opérations de base de données. Elles permettent à vos objets de répondre intelligemment à n'importe quel appel de méthode, même ceux que vous n'avez pas explicitement définis.

challenge icon

Défi

Facile

Construisons un client API dynamique qui utilise des méthodes magiques pour gérer les appels de méthodes de manière flexible. Vous allez créer une classe qui intercepte à la fois les appels de méthodes d'instance et statiques, en les traduisant en réponses de type API significatives sans définir chaque méthode explicitement.

Vous organiserez votre code sur deux fichiers :

  • ApiClient.php — Créez une classe ApiClient qui simule des interactions API en utilisant des méthodes magiques. Votre classe doit avoir une propriété privée $baseUrl définie via le constructeur. Implémentez deux méthodes magiques :
    • __call() — Gère les appels de méthodes d'instance. Lorsqu'une méthode commençant par get est appelée (comme getUsers ou getPosts), extrayez le nom de la ressource (la partie après "get") et retournez "GET [baseUrl]/[resource]: [arguments joined by comma]". Le nom de la ressource doit être converti en minuscules. Si la méthode ne commence pas par "get", retournez "Unknown action: [methodName]".
    • __callStatic() — Gère les appels de méthodes statiques. Lorsqu'une méthode commençant par create est appelée (comme createUser), extrayez le nom de la ressource et retournez "POST /[resource]: [arguments joined by comma]". Le nom de la ressource doit être en minuscules. Pour les méthodes commençant par delete, retournez "DELETE /[resource]: [first argument]". Pour toute autre méthode, retournez "Static action not supported: [methodName]".
  • main.php — Incluez le fichier ApiClient. Vous recevrez trois entrées : une URL de base, un identifiant de ressource et une valeur. Créez une instance de ApiClient avec l'URL de base. Ensuite, affichez quatre lignes :
    • Appelez une méthode get dynamique en utilisant l'identifiant de ressource comme suffixe du nom de la méthode (par exemple, si la ressource est "Users", appelez getUsers) avec la valeur comme argument
    • Appelez getProducts avec deux arguments : "electronics" et "active"
    • Appelez la méthode statique createOrder avec la valeur comme argument
    • Appelez la méthode statique deleteItem avec l'identifiant de ressource comme argument

Les méthodes magiques permettent à votre client API de répondre dynamiquement à n'importe quel appel de méthode. Au lieu de définir getUsers(), getPosts(), getProducts(), et des dizaines d'autres, une seule méthode __call() les gère toutes en examinant le nom de la méthode et en extrayant les informations pertinentes.

Aide-mémoire

La méthode __call() intercepte les appels de méthodes d'instance qui n'existent pas ou sont inaccessibles. Elle reçoit le nom de la méthode et un tableau d'arguments :

<?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");
// Résultat : Called 'sendEmail' with: Hello, World

La méthode __callStatic() intercepte les appels de méthodes statiques. Elle doit être déclarée comme static :

<?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");
// Résultat : Finding by Email: test@example.com

Ces méthodes magiques sont utiles pour créer des API fluides, implémenter le transfert de méthodes ou construire des générateurs de requêtes dynamiques où les noms de méthodes se traduisent en opérations.

Essayez vous-même

<?php

require_once 'ApiClient.php';

// Lire les entrées
$baseUrl = trim(fgets(STDIN));
$resource = trim(fgets(STDIN));
$value = trim(fgets(STDIN));

// TODO: Créer une instance d'ApiClient avec l'URL de base

// TODO: Appeler une méthode get dynamique en utilisant la ressource comme suffixe du nom de la méthode
// Astuce : Utilisez des appels de méthode variables comme $api->{"get" . $resource}($value)

// TODO: Appeler getProducts avec deux arguments : "electronics" et "active"

// TODO: Appeler la méthode statique createOrder avec la valeur comme argument
// Astuce : Utilisez ApiClient::createOrder($value)

// TODO: Appeler la méthode statique deleteItem avec la ressource comme argument

?>
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet