Menu
Coddy logo textTech

__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, World

Statik 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.com

Bu 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.

challenge icon

Görev

Kolay

Metot ç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 bir ApiClient sı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. get ile başlayan bir metot çağrıldığında (örneğin getUsers veya getPosts), 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. create ile başlayan bir metot çağrıldığında (örneğin createUser), kaynak adını çıkarın ve "POST /[resource]: [arguments joined by comma]" döndürün. Kaynak adı küçük harf olmalıdır. delete ile 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 bir ApiClient ö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 get metodu çağırın (örneğin, kaynak "Users" ise getUsers çağırın) ve değeri argüman olarak gönderin
    • getProducts metodunu iki argümanla çağırın: "electronics" ve "active"
    • Statik createOrder metodunu değeri argüman olarak vererek çağırın
    • Statik deleteItem metodunu kaynak tanımlayıcısını argüman olarak vererek çağırın

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

?>
quiz iconKendini test et

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