__call e __callStatic
Fa parte della sezione Programmazione orientata agli oggetti del percorso PHP di Coddy. Lezione 47 di 91.
Proprio come __get() e __set() intercettano l'accesso alle proprietà, i metodi __call() e __callStatic() intercettano le chiamate ai metodi. Vengono attivati quando chiami un metodo che non esiste o non è accessibile su un oggetto o una classe.
Il metodo __call() gestisce le chiamate ai metodi di istanza. Riceve il nome del metodo e un array di argomenti:
<?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");
Output:
Called 'sendEmail' with: Hello, WorldPer le chiamate ai metodi statici, usa __callStatic(). Nota che deve essere dichiarato come 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");
Output:
Finding by Email: test@example.comQuesti metodi magici sono potenti per creare API fluenti, implementare l'inoltro dei metodi o creare generatori di query dinamici, in cui i nomi dei metodi si traducono in operazioni sul database. Consentono ai tuoi oggetti di rispondere in modo intelligente a qualsiasi chiamata di metodo, anche a quelle che non hai definito esplicitamente.
Sfida
FacileCostruiamo un client API dinamico che usa metodi magici per gestire in modo flessibile le chiamate ai metodi. Creerai una classe che intercetta sia le chiamate ai metodi di istanza sia quelle ai metodi statici, trasformandole in risposte significative simili a quelle di un’API senza definire esplicitamente ogni metodo.
Organizzerai il codice in due file:
ApiClient.php: crea una classeApiClientche simula le interazioni con un’API usando metodi magici. La tua classe deve avere una proprietà privata$baseUrl, impostata tramite il costruttore. Implementa due metodi magici:__call(): gestisce le chiamate ai metodi di istanza. Quando viene chiamato un metodo che inizia conget(comegetUsersogetPosts), estrai il nome della risorsa (la parte dopo "get") e restituisci"GET [baseUrl]/[resource]: [arguments joined by comma]". Il nome della risorsa deve essere convertito in minuscolo. Se il metodo non inizia con "get", restituisci"Unknown action: [methodName]".__callStatic(): gestisce le chiamate ai metodi statici. Quando viene chiamato un metodo che inizia concreate(comecreateUser), estrai il nome della risorsa e restituisci"POST /[resource]: [arguments joined by comma]". Il nome della risorsa deve essere in minuscolo. Per i metodi che iniziano condelete, restituisci"DELETE /[resource]: [first argument]". Per qualsiasi altro metodo, restituisci"Static action not supported: [methodName]".
main.php: includi il file ApiClient. Riceverai tre input: un URL di base, un identificatore di risorsa e un valore. Crea un’istanza diApiClientcon l’URL di base. Poi stampa quattro righe:- Chiama un metodo dinamico
get, usando l’identificatore di risorsa come suffisso del nome del metodo (ad esempio, se la risorsa è "Users", chiamagetUsers), passando il valore come argomento - Chiama
getProductscon due argomenti:"electronics"e"active" - Chiama il metodo statico
createOrderpassando il valore come argomento - Chiama il metodo statico
deleteItempassando l’identificatore di risorsa come argomento
- Chiama un metodo dinamico
I metodi magici permettono al tuo client API di rispondere dinamicamente a qualsiasi chiamata di metodo. Invece di definire getUsers(), getPosts(), getProducts() e decine di altri metodi, un unico metodo __call() li gestisce tutti esaminando il nome del metodo ed estraendo le informazioni pertinenti.
Provalo tu
<?php
require_once 'ApiClient.php';
// Leggi gli input
$baseUrl = trim(fgets(STDIN));
$resource = trim(fgets(STDIN));
$value = trim(fgets(STDIN));
// TODO: Crea un'istanza di ApiClient con l'URL di base
// TODO: Chiama un metodo get dinamico usando resource come suffisso del nome del metodo
// Suggerimento: Usa chiamate a metodi variabili come $api->{"get" . $resource}($value)
// TODO: Chiama getProducts con due argomenti: "electronics" e "active"
// TODO: Chiama il metodo statico createOrder con value come argomento
// Suggerimento: Usa ApiClient::createOrder($value)
// TODO: Chiama il metodo statico deleteItem con resource come argomento
?>Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniIntroduzione alla programmazione orientata agli oggettiClassi e oggettiLa parola chiave $thisMetodiProprietàCostruttore (__construct)Distruttore (__destruct)Riepilogo - Calcolatrice semplice4Ereditarietà
Ereditarietà di baseLa parola chiave parent::Sovrascrittura dei metodiLa parola chiave finalClassi astratteRiepilogo - Gerarchia dei dipendenti7Incapsulamento
Pubblico, Protetto, PrivatoApprofondimento sui modificatori di accessoGetter e SetterOccultamento delle informazioniPromozione dei parametri del costruttore (8.0)Riepilogo - Sistema di gestione dei registri degli studenti10Concetti avanzati di programmazione a oggetti
Composizione vs ereditarietàDependency InjectionClassi anonimeEnumerazioni (PHP 8.1)Fibers (PHP 8.1)Approfondimento sulla clonazione degli oggettiGeneratori e iteratori13Modelli di progettazione, parte 2
Modello CommandModello AdapterModello DecoratorModello Template MethodModello StateModello CompositeModello Repository2Namespace e autoloading
Introduzione ai namespaceLa keyword useStandard di autoloading PSR-4Autoloader di ComposerRiepilogo - Progetto organizzato5Interfacce e contratti
Introduzione alle interfacceImplementare le interfacceImplementare più interfacceInterfaccia vs classe astrattaType hinting con le interfacceRiepilogo - Calcolatore di forme8Metodi magici
Introduzione ai metodi magici__toString e __debugInfo__get, __set, __isset, __unset__call e __callStatic__clone e clonazione degli oggetti__serialize e __unserializeRiepilogo - Collezione personalizzata11Sistema dei tipi e gestione degli errori
Dichiarazioni di tipoTipi nullableTipi unione e intersezioneClassi di eccezioneGerarchia di eccezioni personalizzataTry, Catch, FinallyRiepilogo - Validatore di moduli14Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e Utente3Proprietà delle classi
Proprietà di istanza e staticheCostanti nelle classiMetodi e proprietà staticiProprietà private e protectedProprietà readonly (PHP 8.1)Riepilogo - Gestore di conti bancari6Polimorfismo
Ridefinizione dei metodi, ripresaPolimorfismo tramite interfacceSuggerimenti sui tipi e tipi UnionBinding statico tardivoRiepilogo - Processore di pagamenti9Tratti
Introduzione ai trattiUtilizzare più trattiRisoluzione dei conflitti tra trattiMetodi astratti nei trattiTratti vs ereditarietà12Design pattern - Parte 1
Introduzione ai design patternPattern SingletonPattern FactoryPattern ObserverPattern StrategyEsercitati da solo: Compilatore PHP online