__call & __callStatic
Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 47 / 91.
Tıpkı __get() ve __set() yöntemlerinin özellik erişimini yakalaması gibi, __call() ve __callStatic() yöntemleri de metot çağrılarını yakalar. Bir nesne veya sınıf üzerinde var olmayan veya erişilemeyen bir metodu çağırdığınızda tetiklenirler.
__call() yöntemi, örnek metot çağrılarını işler. Metot adını ve bir argüman dizisini alır:
<?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");
Çıktı:
Called 'sendEmail' with: Hello, WorldStatik metot çağrıları için __callStatic() kullanın. Bunun static olarak bildirilmesi gerektiğine dikkat edin:
<?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");
Çıktı:
Finding by Email: test@example.comBu sihirli metotlar; akıcı API'ler oluşturmak, metot yönlendirmeyi uygulamak veya metot adlarının veritabanı işlemlerine dönüştüğü dinamik sorgu oluşturucular inşa etmek için güçlüdür. Nesnelerinizin, açıkça tanımlamadığınız metot çağrıları da dahil olmak üzere her türlü metot çağrısına akıllıca yanıt vermesini sağlarlar.
Görev
KolayMetot çağrılarını esnek bir şekilde yönetmek için sihirli metotlar (magic methods) kullanan dinamik bir API istemcisi oluşturalım. Her metodu açıkça tanımlamadan, hem örnek (instance) hem de statik metot çağrılarını yakalayan ve bunları anlamlı API benzeri yanıtlara dönüştüren bir sınıf oluşturacaksınız.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
ApiClient.php— Sihirli metotları kullanarak API etkileşimlerini simüle eden birApiClientsınıfı oluşturun. Sınıfınızın, yapıcı (constructor) aracılığıyla ayarlanan özel bir$baseUrlözelliği olmalıdır. İki sihirli metot uygulayın:__call()— Örnek metot çağrılarını yönetir.getile başlayan bir metot çağrıldığında (örneğingetUsersveyagetPosts), kaynak adını ("get"ten sonraki kısım) çıkarın ve"GET [baseUrl]/[resource]: [arguments joined by comma]"döndürün. Kaynak adı küçük harfe dönüştürülmelidir. Metot "get" ile başlamıyorsa,"Unknown action: [methodName]"döndürün.__callStatic()— Statik metot çağrılarını yönetir.createile başlayan bir metot çağrıldığında (örneğincreateUser), kaynak adını çıkarın ve"POST /[resource]: [arguments joined by comma]"döndürün. Kaynak adı küçük harf olmalıdır.deleteile başlayan metotlar için"DELETE /[resource]: [first argument]"döndürün. Diğer tüm metotlar için"Static action not supported: [methodName]"döndürün.
main.php— ApiClient dosyasını dahil edin. Üç girdi alacaksınız: bir temel URL (base URL), bir kaynak tanımlayıcı (resource identifier) ve bir değer. Temel URL ile birApiClientörneği oluşturun. Ardından dört satır yazdırın:- Kaynak tanımlayıcısını metot adı son eki olarak kullanarak dinamik bir
getmetodu çağırın (örneğin, kaynak "Users" isegetUsersçağırın) ve değeri argüman olarak gönderin getProductsmetodunu iki argümanla çağırın:"electronics"ve"active"- Statik
createOrdermetodunu değeri argüman olarak vererek çağırın - Statik
deleteItemmetodunu kaynak tanımlayıcısını argüman olarak vererek çağırın
- Kaynak tanımlayıcısını metot adı son eki olarak kullanarak dinamik bir
Sihirli metotlar, API istemcinizin herhangi bir metot çağrısına dinamik olarak yanıt vermesini sağlar. getUsers(), getPosts(), getProducts() ve düzinelerce başka metodu tek tek tanımlamak yerine, tek bir __call() metodu, metot adını inceleyerek ve ilgili bilgileri çıkararak hepsini yönetir.
Kopya kağıdı
__call() yöntemi, mevcut olmayan veya erişilemeyen örnek yöntemi çağrılarını yakalar. Yöntem adını ve bir dizi argümanı alır:
<?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, World
__callStatic() yöntemi statik yöntem çağrılarını yakalar. static olarak tanımlanmalıdır:
<?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.com
Bu sihirli yöntemler; akıcı API'ler (fluent APIs) oluşturmak, yöntem yönlendirme (method forwarding) uygulamak veya yöntem adlarının işlemlere dönüştüğü dinamik sorgu oluşturucular inşa etmek için kullanışlıdır.
Kendin dene
<?php
require_once 'ApiClient.php';
// Girdileri oku
$baseUrl = trim(fgets(STDIN));
$resource = trim(fgets(STDIN));
$value = trim(fgets(STDIN));
// TODO: Temel URL ile bir ApiClient örneği oluşturun
// TODO: Kaynak adını metot adı son eki olarak kullanarak dinamik bir get metodu çağırın
// İpucu: $api->{"get" . $resource}($value) gibi değişken metot çağrılarını kullanın
// TODO: getProducts metodunu iki argümanla çağırın: "electronics" ve "active"
// TODO: Değeri argüman olarak kullanarak statik createOrder metodunu çağırın
// İpucu: ApiClient::createOrder($value) kullanın
// TODO: Kaynağı argüman olarak kullanarak statik deleteItem metodunu çağırın
?>Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesneler$this Anahtar KelimesiMetotlarÖzelliklerYapıcı Metot (__construct)Yıkıcı Metot (__destruct)Özet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımparent:: Anahtar KelimesiMetot Geçersiz Kılmafinal Anahtar KelimesiSoyut SınıflarÖzet - Çalışan Hiyerarşisi7Kapsülleme
Public, Protected, PrivateErişim Belirleyicilere Derinlemesine BakışGetter ve Setter MetotlarıBilgi GizlemeConstructor Promotion (8.0)Özet - Öğrenci Kayıt Sistemi10İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımDependency InjectionAnonim SınıflarEnum'lar (PHP 8.1)Fiber'lar (PHP 8.1)Nesne Klonlama: Derinlemesine İncelemeGenerator'lar ve Iterator'lar13Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıRepository Kalıbı2İsim Alanları ve Autoloading
İsim Alanlarına Girişuse Anahtar KelimesiPSR-4 Autoloading StandartıComposer AutoloaderÖzet - Düzenli Proje5Arayüzler ve Sözleşmeler
Arayüzlere GirişArayüzleri UygulamaBirden Fazla Arayüz UygulamaArayüz vs Soyut SınıfArayüzler ile Tip BelirlemeÖzet - Şekil Hesaplayıcı8Sihirli Metotlar
Sihirli Metotlara Giriş__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Nesne Klonlama__serialize & __unserializeÖzet - Özel Koleksiyon3Sınıf Özellikleri
Örnek ve Statik ÖzelliklerSınıflarda SabitlerStatik Metotlar ve ÖzelliklerPrivate ve Protected ÖzelliklerReadonly Özellikler (PHP 8.1)Özet - Banka Hesabı Yöneticisi6Çok Biçimlilik
Metot Geçersiz Kılmaya Yeniden BakışArayüzler ile Çok BiçimlilikType Hinting ve Union TypesLate Static BindingÖzet - Ödeme İşlemcisi9Trait'ler
Trait'lere GirişÇoklu Trait KullanımıTrait Çakışma ÇözümüTrait'lerde Soyut MetotlarTrait'ler ve Kalıtım12Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı15Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi