__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, WorldPour 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.comCes 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.
Défi
FacileConstruisons 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 classeApiClientqui simule des interactions avec une API à l’aide de méthodes magiques. Votre classe doit posséder une propriété$baseUrlprivé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 pargetest appelée (commegetUsersougetPosts), 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 parcreateest appelée (commecreateUser), 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 pardelete, 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 deApiClientavec l’URL de base. Affichez ensuite quatre lignes :- Appelez une méthode dynamique
geten utilisant l’identifiant de ressource comme suffixe du nom de méthode (par exemple, si la ressource est "Users", appelezgetUsers) avec la valeur comme argument - Appelez
getProductsavec deux arguments :"electronics"et"active" - Appelez la méthode statique
createOrderavec la valeur comme argument - Appelez la méthode statique
deleteItemavec l’identifiant de ressource comme argument
- Appelez une méthode dynamique
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
?>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
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses et objetsLe mot-clé $thisMéthodesPropriétésConstructeur (__construct)Destructeur (__destruct)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLe mot-clé parent::Redéfinition des méthodesLe mot-clé finalClasses abstraitesRécapitulatif – Hiérarchie des employés7Encapsulation
Public, Protected, PrivateModificateurs d’accès en profondeurAccesseurs et mutateursDissimulation de l’informationPromotion des constructeurs (8.0)Récapitulatif – Système de fiches étudiant10Concepts avancés de la POO
Composition ou héritageInjection de dépendancesClasses anonymesÉnumérations (PHP 8.1)Fibres (PHP 8.1)Approfondissement du clonage d’objetsGénérateurs et itérateurs13Patrons de conception – Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode modèlePatron ÉtatPatron CompositePatron Dépôt2Espaces de noms et chargement automatique
Introduction aux espaces de nomsLe mot-clé useNorme de chargement automatique PSR-4Autoloader de ComposerRécapitulatif - Projet organisé5Interfaces et contrats
Introduction aux interfacesImplémentation des interfacesImplémentation de plusieurs interfacesInterface ou classe abstraiteIndication de type avec les interfacesRécapitulatif - Calculateur de formes8Méthodes magiques
Introduction aux méthodes magiques__toString et __debugInfo__get, __set, __isset, __unset__call et __callStatic__clone et clonage d’objets__serialize et __unserializeRécapitulatif - Collection personnalisée3Propriétés de classe
Propriétés d’instance vs statiquesConstantes dans les classesMéthodes et propriétés statiquesPropriétés privées et protégéesPropriétés en lecture seule (PHP 8.1)Récapitulatif - Gestionnaire de comptes bancaires6Polymorphisme
Révision de la redéfinition des méthodesPolymorphisme via les interfacesAnnotations de type et types unionLiaison statique tardiveRécapitulatif - Processeur de paiements9Traits
Introduction aux traitsUtilisation de plusieurs traitsRésolution des conflits entre traitsMéthodes abstraites dans les traitsTraits par rapport à l’héritage12Patrons de conception – Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron StrategyEntraînez-vous par vous-même : Compilateur PHP en ligne