Menu
Coddy logo textTech

__call et __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(). Remarquez 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 la redirection de méthodes ou créer 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 à tout appel de méthode, même à ceux que vous n’avez pas définis explicitement.

challenge icon

Défi

Facile

Construisons un client API dynamique qui utilise des méthodes magiques pour gérer les appels de méthodes avec flexibilité. Vous allez créer une classe qui intercepte les appels de méthodes d’instance et statiques, en les transformant en réponses pertinentes de type API, sans définir explicitement chaque méthode.

Vous allez organiser votre code sur deux fichiers :

  • ApiClient.php : créez une classe ApiClient qui simule des interactions avec une API à l’aide de méthodes magiques. Votre classe doit posséder une propriété $baseUrl privée, définie par 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 située après "get") et renvoyez "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", renvoyez "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 renvoyez "POST /[resource]: [arguments joined by comma]". Le nom de la ressource doit être en minuscules. Pour les méthodes commençant par delete, renvoyez "DELETE /[resource]: [first argument]". Pour toute autre méthode, renvoyez "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. Affichez ensuite quatre lignes :
    • Appelez une méthode dynamique get en utilisant l’identifiant de ressource comme suffixe du nom de 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 méthodes, une seule méthode __call() les gère toutes en examinant le nom de la méthode et en extrayant les informations pertinentes.

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 resource comme suffixe du nom de méthode
// Hint: Utiliser 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 value comme argument
// Hint: Utiliser ApiClient::createOrder($value)

// TODO: Appeler la méthode statique deleteItem avec resource 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

Entraînez-vous par vous-même : Compilateur PHP en ligne