__call i __callStatic
Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 47 z 91.
Podobnie jak __get() i __set() przechwytują dostęp do właściwości, metody __call() i __callStatic() przechwytują wywołania metod. Są uruchamiane, gdy wywołujesz metodę, która nie istnieje lub jest niedostępna w obiekcie albo klasie.
Metoda __call() obsługuje wywołania metod instancji. Otrzymuje nazwę metody i tablicę argumentów:
<?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");
Wynik:
Called 'sendEmail' with: Hello, WorldW przypadku wywołań metod statycznych użyj __callStatic(). Zwróć uwagę, że musi być zadeklarowana jako 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");
Wynik:
Finding by Email: test@example.comTe magiczne metody są przydatne do tworzenia płynnych interfejsów API, implementowania przekazywania wywołań metod lub budowania dynamicznych kreatorów zapytań, w których nazwy metod przekładają się na operacje na bazie danych. Pozwalają obiektom inteligentnie reagować na każde wywołanie metody, nawet jeśli nie zdefiniowano jej jawnie.
Wyzwanie
ŁatwyZbudujmy dynamicznego klienta API, który używa metod magicznych do elastycznej obsługi wywołań metod. Utworzysz klasę, która przechwytuje wywołania zarówno metod instancji, jak i metod statycznych, przekształcając je w odpowiedzi przypominające odpowiedzi API bez jawnego definiowania każdej metody.
Podzielisz kod na dwa pliki:
ApiClient.php: Utwórz klasęApiClient, która symuluje interakcje z API za pomocą metod magicznych. Twoja klasa powinna mieć prywatną właściwość$baseUrl, której wartość jest ustawiana przez konstruktor. Zaimplementuj dwie metody magiczne:__call(): Obsługuje wywołania metod instancji. Gdy zostanie wywołana metoda zaczynająca się odget(na przykładgetUserslubgetPosts), wyodrębnij nazwę zasobu (część po "get") i zwróć"GET [baseUrl]/[resource]: [arguments joined by comma]". Nazwa zasobu powinna zostać zamieniona na małe litery. Jeśli metoda nie zaczyna się od "get", zwróć"Unknown action: [methodName]".__callStatic(): Obsługuje wywołania metod statycznych. Gdy zostanie wywołana metoda zaczynająca się odcreate(na przykładcreateUser), wyodrębnij nazwę zasobu i zwróć"POST /[resource]: [arguments joined by comma]". Nazwa zasobu powinna składać się z małych liter. W przypadku metod zaczynających się oddeletezwróć"DELETE /[resource]: [first argument]". W przypadku każdej innej metody zwróć"Static action not supported: [methodName]".
main.php: Dołącz plik ApiClient. Otrzymasz trzy dane wejściowe: podstawowy adres URL, identyfikator zasobu i wartość. Utwórz instancjęApiClientz podstawowym adresem URL. Następnie wypisz cztery wiersze:- Wywołaj dynamiczną metodę
get, używając identyfikatora zasobu jako przyrostka nazwy metody (na przykład, jeśli zasobem jest "Users", wywołajgetUsers), i przekaż wartość jako argument - Wywołaj
getProductsz dwoma argumentami:"electronics"i"active" - Wywołaj statyczną metodę
createOrder, przekazując wartość jako argument - Wywołaj statyczną metodę
deleteItem, przekazując identyfikator zasobu jako argument
- Wywołaj dynamiczną metodę
Metody magiczne pozwalają klientowi API dynamicznie reagować na dowolne wywołanie metody. Zamiast definiować getUsers(), getPosts(), getProducts() i dziesiątki innych metod, jedna metoda __call() obsługuje je wszystkie, analizując nazwę metody i wyodrębniając odpowiednie informacje.
Spróbuj swoich sił
<?php
require_once 'ApiClient.php';
// Odczytaj dane wejściowe
$baseUrl = trim(fgets(STDIN));
$resource = trim(fgets(STDIN));
$value = trim(fgets(STDIN));
// TODO: Utwórz instancję ApiClient z bazowym adresem URL
// TODO: Wywołaj dynamiczną metodę get, używając resource jako przyrostka nazwy metody
// Wskazówka: Użyj wywołania metody o zmiennej nazwie, np. $api->{"get" . $resource}($value)
// TODO: Wywołaj getProducts z dwoma argumentami: "electronics" i "active"
// TODO: Wywołaj statyczną metodę createOrder z value jako argumentem
// Wskazówka: Użyj ApiClient::createOrder($value)
// TODO: Wywołaj statyczną metodę deleteItem z resource jako argumentem
?>Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektySłowo kluczowe $thisMetodyWłaściwościKonstruktor (__construct)Destruktor (__destruct)Powtórka — prosty kalkulator4Dziedziczenie
Podstawy dziedziczeniaSłowo kluczowe parent::Przesłanianie metodSłowo kluczowe finalKlasy abstrakcyjnePowtórzenie – hierarchia pracowników7Enkapsulacja
Public, protected, privateModyfikatory dostępu w szczegółachGettery i setteryUkrywanie informacjiPromocja parametrów konstruktora (8.0)Podsumowanie — system ewidencji studentów2Przestrzenie nazw i autoloading
Wprowadzenie do przestrzeni nazwSłowo kluczowe useStandard autoloadingu PSR-4Autoloader ComposeraPodsumowanie – uporządkowany projekt5Interfejsy i kontrakty
Wprowadzenie do interfejsówImplementowanie interfejsówImplementowanie wielu interfejsówInterfejs a klasa abstrakcyjnaPodpowiadanie typów za pomocą interfejsówPodsumowanie — kalkulator kształtów8Metody magiczne
Wprowadzenie do metod magicznych__toString i __debugInfo__get, __set, __isset, __unset__call i __callStatic__clone i klonowanie obiektów__serialize i __unserializePodsumowanie — własna kolekcja11System typów i obsługa błędów
Deklaracje typówTypy nullableTypy sumy i przecięciaKlasy wyjątkówNiestandardowa hierarchia wyjątkówTry, Catch, FinallyPodsumowanie — walidator formularzy14Projekt: Zarządzanie biblioteką
Przegląd projektuKlasy książki i użytkownika3Właściwości klas
Właściwości instancji a właściwości statyczneStałe w klasachMetody i właściwości statyczneWłaściwości prywatne i chronioneWłaściwości tylko do odczytu (PHP 8.1)Podsumowanie — menedżer kont bankowych6Polimorfizm
Ponowne omówienie nadpisywania metodPolimorfizm za pomocą interfejsówPodpowiedzi typów i typy sumyPóźne wiązanie statycznePodsumowanie — procesor płatności9Cechy
Wprowadzenie do cechKorzystanie z wielu cechRozwiązywanie konfliktów cechMetody abstrakcyjne w cechachCechy a dziedziczenie12Wzorce projektowe, część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec ObserverWzorzec StrategyPoćwicz samodzielnie: Kompilator PHP online