Kategoriler
Teknik

PHP’de Geriçağırım İşlevleri (Fonksiyon ve Yöntemler) (1)

Bu yazıda, PHP’de geriçağırım işlevlerinden bahsedip, nerelerde nasıl kullanıldığını öğreneceğiz.

Geriçağırım (callback) işlevleri (functions) aslında PHP’de bildiğimiz fonksiyonları ifade eder. PHP’nin 5.4 sürümünden itibarent bir callable türü ile kendilerini belli ederler.

PHP’de iki çeşit işlev (fonksiyon) vardır. Birincisi adı sanı belli olan işlevler, ikincisi anonim işlevler. Adı sanı belli dediğimiz işlevler, şu ana kadar bildiğimiz kullandığımız fonksiyonlardır. Bunları çağırmanın/kullanmanın birden fazla yöntemi vardır. Birazdan bunları işleyeceğiz. İkinci olan anonim işlevler ise, fonksiyonlarla hemen hemen aynı olup, fonksiyonlar gibi tanımlanmaz. Fark olarak anonim işlevler bir değişkene atanabilir. (en basit örneğiyle, bunun dışında farklı şeylere de yarar, göreceğiz).

PHP’de bir değerin çağırılabilir olup olmadığını is_callable işleviyle kontrol edebiliyoruz. İki tane örnek verelim:

function selam_ver(string $isim): string
{
    return "Selamlar sevgili $isim";
}

var_dump(is_callable('selam_ver')); // true

$selamVer = function(string $isim): string {
    return "Selamlar sevgili $isim";
};

var_dump(is_callable($selamVer)); // true
var_dump(is_callable('isset')); // true çünkü böyle bir fonksiyon zaten var, PHP'de öntanımlı
var_dump(is_callable('herhangi_fonksiyon')); // false, çünkü herhangi_fonksiyon adında bir fonksiyon tanımlamadık

Buradan doğru, bir işlevin (fonksiyonun) tanımlı olup olmadığını veya bir değişkenin işlev olup olmadığını öğrenebiliyoruz. Aynı zamanda bir sınıf içerisindeki statik bir işlevin var olup olmadığını da öğrenebiliriz:

class Selamlayici
{
    public static function selamla(string $isim): string
    {
        return "Selamlar sevgili $isim";
    }
}

var_dump(is_callable('Selamlayici::selamla')); // true

Peki sınıf dinamikse nasıl öğreneceğiz? Şöyle:

class Selamlayici
{
    public function selamla(string $isim): string
    {
        return "Selamlar sevgili $isim";
    }
}

var_dump(is_callable([new Selamlayici, 'selamla'])); // true

Dinamik bir sınıfta dize içerisindeki ilk eleman sınıfın örneğini, ikinci eleman ise yöntemi (metodu) bulundurur.

Şimdi, buraya kadar bazı şeylere tamam dedik. Neyin ne olduğunu nasıl öğreneceğimizi anladık. Peki bunları nasıl kullanacağız. İşlevleri kullanmanın en basit yolu, herkesin bildiği gibi selam_ver('Ali') kodu gibidir. Ama PHP’de işlevleri kullanıp çağırabilmek için birden fazla yöntem vardır. Hemen görelim:

selam_ver('Ali'); // "Selamlar sevgili Ali"
$selamVer('Renas'); // "Selamlar sevgili Renas"
Selamlayici::selamla('Deniz'); // "Selamlar sevgili Deniz"
$selamlayici = new Selamlayici;
$selamlayici->selamla('Nar'); // "Selamlar sevgili Nar"

Bu gördüğümüz klasik bir biçimde işlevleri çağırmamıza yarar, birçoğumuz bilir. Başka hangi yöntemler var işlevleri çağırmak için? İlk iki tanesi call_user_func ve call_user_func_array işlevidir. Bunlar tanımlı bir işlevi bir işlev aracılığı ile çağırır. Görelim:

function parametresiz_selamlama(): string
{
    return 'Selamlar sevgili Django!';
}

var_dump(call_user_func('parametresiz_selamlama')); // "Selamlar sevgili Django!"

Yukarıdaki örnekte, parametresi olmayan bir işlevi parametresiz_selamlama() kodu ile değil, farklı bir yöntemle çağırdık. Peki neden böyle bir şeye ihtiyaç duyduk? Pek çok sebebi olabilir. Bunun normal bir fonksiyon değilde, bir sınıf yöntemi olduğunu varsaydığımızda bunu bir MVC uygulaması geliştirirken kullanabilirdik.

Peki ilk başlarda tanımladığımız parametreli işlevleri nasıl çağıracağız:

// artık var_dump işlevini kullanmadan yazacağım, görsel olarak karışık görünmesin diye

call_user_func_array('selam_ver', ['Ali']); // "Selamlar sevgili Ali"
call_user_func_array($selamVer, ['Renas']); // "Selamlar sevgili Renas"
call_user_func_array('Selamlayici::selamla', ['Deniz']); // "Selamlar sevgili Deniz"
call_user_func_array([new Selamlayici, 'selamla'], ['Nar']); // "Selamlar sevgili Nar"
call_user_func_array('parametresiz_selamlama'); // "Selamlar sevgili Django!"

Yukarıda daha normal biçimde çağırdığımız işlevleri, şimdi başka (call_user_func_array) bir işlev aracılığıyla çağırdık. Anonim bir işlevi şu şekilde de çağırabiliriz:

call_user_func(function(){
    echo 'Hoş geldiniz';
});

Peki, anonim işlevleri gerçek hayatta nasıl kullanacağız? En basit haliyle şunu yazalım:

function ozel_selamlama(string $isim, callable $ozelSelamla): string
{
    return call_user_func_array($ozelSelamla, [$isim]);
    // veya $ozelSelamla($isim); bu ikisi aynı şey
}

ozel_selamla('Ali', function($isim): string {
    return "Bu farklı bir selamlama biçimi sevgili {$isim}!";
}); // "Bu farklı bir selamlama biçimi sevgili Ali!"

Yukarıdaki örnekte, özel bir selamlama mesajı vermek için iki parametreli bir işlev/fonksiyon oluşturduk. İlk parametre selamlanacak kişinin adını alıyor, ikinci parametre ise nasıl selamlanacağını ayarlayan anonim bir işlevi alıyor.

Başka bir örnek daha verelim. Bu sefer daha spesifik bir örnek verelim:

function eklemeli_selamla(string $isim, ?callable $ek = null): string
{
    $selamlama = "Selamlar sevgili $isim";

    if (!is_null($ek)) {
        return $selamlama . $ek($isim);
        // veya:
        // return $selamlama . call_user_func_array($ek, [$isim]);
    }

    return $selamlama;
}

eklemeli_selamlama('Deniz'); // "Selamlar sevgili Deniz"
eklemeli_selamlama('Deniz', function($isim): string {
    return ". Adının $isim olduğunu biliyorum!";
}); // "Selamlar sevgili Deniz. Adının Deniz olduğunu biliyorum!"

Şimdilik bahsedeceklerimiz bunlar. Bu yazının bir devamı daha olacak. Devamı niteliğindeki yazıda ise Closure sınıfı, sınıfların bir işlev olarak çağırılabilmesi ve Reflection sınıfından bahsetmeyi planlıyorum.

İyi çalışmalar.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir