Yücel Alkan

PHP OOP Yapısında Sihirbaz Metotlar

Merhaba. Bu yazımda PHP Object Oriented Programming yapısındaki sihirbaz metotlardan bahsedeceğim. Belirlenen durumlarda kendiliğinden çalışan metotlara Sihirbaz Metotlar denir. Sihirbaz metotlar PHP'de öntanımlı olarak gelirler. Bu metotların isimlerinin başında iki alt tire (__) bulunur. Bu yüzden kendi tanımladığımız metotların başına iki alt tire koyulmaması PHP geliştiricileri tarafından tavsiye edilir. 

Sihirbaz metotlar, otomatik olarak çalışır yani bu metotlar kendiliğinden tetiklenir. Mesela; nesne oluşturulduğu zaman, nesne yok edildiği zaman, sınıf içerisinde bulunmayan bir parametreye (özelliğe) değer girilmeye çalışıldığı an, sınıf içinde tanımlanmamış bir fonksiyon kullanılmaya çalışıldığı an gibi. İşte buna benzeyen ve daha önce belirlenmiş durumlarda, sihirbaz metotlar kendiliğinden çalışır. 

Bu arada küçük bir not düşmek lazım. Aklınıza, tanımlarken function ifadesi kullanıyoruz ama neden metot olarak isimlendiriyoruz şeklinde bir soru gelmiş olabilir. Function dediğimiz yapılar hem class içinde hem de class dışında tanımlanan yapılardır. Class dışında function adını alınırken, class içinde ise metot veya function olarak isimlendirilir. Yani OOP yapısında class içinde metot ile fonksiyon kavramlarının farkı yoktur diyebiliriz.

Sihirbaz metotların ne olduğunu aşağıdaki yapıları inceledikten sonra daha net anlayabiliriz. O zaman ilk olarak construct sihirbaz metoduyla başlayalım.

1. __construct

Construct kurmak, bina etmek, inşa etmek anlamlarına gelir. Bu yüzden neredeyse tüm programlama dillerinde construct metoduna "kurucu metot" da denir. Construct, nesne oluşturulduğu an çalışan fonksiyondur. Genellikle sınıfın çalışması için gerekli olan bilgiler burada girilir ve gerekli ayarlar yapılır. 

Basit bir kullanımla başlayalım.

class Kitap
{
    public $kitapAdi;
    public $yazar;
    public $fiyat;

    public function __construct()
    {
        echo "Nesne oluşturuldu";
    }
}

$kitap = new Kitap();

Kitap sınıfına ait yeni bir nesne oluşturduğumuz zaman __construct fonksiyonu otomatik olarak çalışacak ve bu fonksiyon içinde tanımlanan işlemler gerçekleştirilecektir. Yani sayfaya "Nesne oluşturuldu" şeklinde bir metin basılacaktır. Dikkat ederseniz biz $kitap adında bir nesne tanımladıktan sonra hiçbir fonksiyonu çağırmadık. Ancak __construct metodu kendiliğinden çalıştı. İşte sihirbaz metotlar tam olarak böyle bir yapıya sahip. 

Şimdi bu yapıyı biraz daha anlamlı hale getirelim. Biz şu ana kadar nesne tanımladıktan sonra tek tek özelliklerini yazıyorduk. Tıpkı aşağıdaki gibi.

$kitap = new Kitap();
$kitap->kitapAdi = "Kalplerin Keşfi";
$kitap->yazar = "İmam Gazzali";
$kitap->fiyat = 18.50;

İşte bu tanımlamaları tek tek yapmaktansa __construct fonksiyonu içinde yapabiliriz. Yani aşağıdaki gibi. 

class Kitap
{
    public $kitapAdi;
    public $yazar;
    public $fiyat;

    public function __construct($gKitapAdi, $gYazar, $gFiyat)
    {
        $this->kitapAdi = $gKitapAdi;
        $this->yazar = $gYazar;
        $this->fiyat = $gFiyat;
    }
}

$kitap = new Kitap("Kalplerin Keşfi", "İmam Gazzali", 18.50);

Bu şekilde bir nesnenin çalışması için gerekli olan bilgileri __construct metodu içinde girebilir ya da bu class'ın çalışması için gereken ayarları burada yapabilirsiniz. 

2. __destruct 

Destruct metodu, construct metodunun zıttıdır diyebiliriz. __destruct() sihirbaz metodu, oluşturulan nesne ile ilgili işlemler bittiği an çalışan sihirli metottur. Oluşturduğumuz bir nesne ile ilgili işlemler bittikten sonra bu nesne bellekten silnecektir. İşte bu silme işlemi öncesinde __destruct() sihirbaz metoduyla istediğiniz işlemleri yapabilirsiniz. 

Destruct sihirbaz metodu birçok programlama dilinde destructor yani yıkıcı metot olarak bilinir. Temel amacı oluşturulan nesnenin kullandığı kaynakları temizlemektir. Oluşturduğumuz nesne bir dosya açmış olabilir, socket bağlantısı kurmuş olabilir. Destruct metodu içerisinde açık olan dosya ve socket bağlantılarını kapatabilirsiniz. Yine aynı şekilde bu nesne veritabanı bağlantısı kurmuş olabilir. Bu veritabanı bağlantısını da yine destructor yani yıkıcı metot içinde kapatabilirsiniz. 

Bir nesne ile ilgili işlemler bittiği an bu nesne bellekten silinecektir, dedik. Öyleyse bu nesnenin açtığı dosya ve socket bağlantısı ya da kurduğu veritabanı bağlantısının hiçbir işlevi kalmamıştır. Ancak bu bağlantılar bellekte yer kaplamaya devam edecektir. İşte __destruct() sihirbaz metoduyla açık olan tüm dosya ve bağlantıları kapatarak bellek temizleme yani kaynak temizleme işlemi yapaibilirsiniz.

class Kitap
{
    public $kitapAdi;
    public $yazar;
    public $fiyat;

    public function __construct($gKitapAdi, $gYazar, $gFiyat)
    {
        $this->kitapAdi = $gKitapAdi;
        $this->yazar = $gYazar;
        $this->fiyat = $gFiyat;
    }

    public function zamYap($miktar)
    {
        $this->fiyat += $miktar;
    }

    public function __destruct()
    {
        echo "Destruct metodu çalıştı";
    }
}

$kitap = new Kitap("Kalplerin Keşfi", "İmam Gazzali", 18.50);

$kitap->zamYap(2);

Yukarıdaki örnekte nesne oluşturulduktan sonra bir de zamYap fonksiyonu çağırılmış ve bu nesne ile ilgili işlemler bitmiştir. İşte tam da bu noktada, yani nesne ile ilgili işlemler bittiği an __destruct fonksiyonu devreye girecek ve burada belirlenen işlemler çalışacaktır. Yani ekrana "Destruct metodu çalıştı" şeklinde bir uyarı yazısı verildikten sonra nesneye ait özellikler silinecektir. 

Dilerseniz kendiniz de unset komutuyla nesneyi ortadan kaldırarak da __destruct metodunun çalışmasını sağlayabilirsiniz. 

unset($kitap);

3. __get 

Class içerisinde tanımlanmamış bir özelliğe yani değişkene ulaşmak istediğimizde çalışır. Yine private veya protected olarak tanımlanmış ve class dışından erişim izni olmayan bir değişkene erişim sağladığımızda bu fonksiyon çalışır. 

class Musteri
{
    public $adSoyad;
    private $bakiye = 5000;

    public function __get($degisken)
    {
        echo "$degisken adında bir özellik yok veya erişim izniniz bulunmamaktadır.";
    }
}

$musteri = new Musteri();
$musteri->adSoyad = "Yücel Alkan";

echo $musteri->bakiye;      // private olduğu için hata verecektir
echo $musteri->meslek;      // böyle bir özellik olmadığı için hata verecektir. 

Yukarıdaki satırları çalıştırdığımız zaman aşağıdaki hatalarla karşılaşacağız. 

bakiye adında bir özellik yok veya erişim izniniz bulunmamaktadır.
meslek adında bir özellik yok veya erişim izniniz bulunmamaktadır.

4. __set

Class içerisinde tanımlanmamış bir özelliğe yani değişkene değer atamak istediğimizde çalışır. Yine private veya protected olarak tanımlanmış ve class dışından erişim izni olmayan bir değişkene değer atamak istediğimizde bu fonksiyon çalışır. __set metodu iki farklı parametre alır. İlk parametre değer atanmak istenen özellik adını yani değişken adını verirken, ikinci parametre de bu değişkene atanmak istenen değeri verecektir. 

class Futbolcu
{
    public $adSoyad;
    private $takim;

    public function __set($degisken, $deger)
    {
        echo "$degisken adında bir özellik yok veya erişim izniniz bulunmamaktadır.";
    }
}

$salah = new Futbolcu();
$salah->adSoyad = "Mohamed Salah";

$salah->takim = "Liverpool";        // private olduğu için hata verecektir. 
$salah->boy = 178;                  // böyle bir özellik olmadığı için hata verecektir.

Yukarıdaki örnekte $salah adında bir nesne tanımlayıo, ad soyad özelliğine değer atadım. Çünkü adSoyad özelliği public olarak tanımlanmış. Ancak private olarak tanımlanan $takim değişkenine değer atamak istediğimde veya class içerisinde tanımlanmamış $boy özelliğine değer vermek istediğimde __set() fonksiyonu çalışacaktır. Bu kodların çıktısı aşağıdaki gibi olacaktır. 

takim adında bir özellik yok veya erişim izniniz bulunmamaktadır.
boy adında bir özellik yok veya erişim izniniz bulunmamaktadır.
5. __call

Class içerisinde tanımlanmayan bir metodu yani fonksiyonu çalıştırmak istediğimiz tetiklenen metottur. İki tane parametre ile birlikte çalışır. İlk parametre metot adını, ikinci parametre ise parametreleri içerir. 

class Uye
{
    public $adSoyad;
    public $meslek;

    public function __call($isim, $parametreler)
    {
        echo "$isim adında bir fonksiyon bulunmuyor";
    }
}

$uye  = new Uye();  
$uye->sifreDegistir();

Dikkat ettiyseniz Uye isimli class içerisinde sifreDegistir() adında bir metot bulunmuyor. İşte bu şekilde class içerisinde bulunmayan bir metoda erişim sağlamaya çalıştığımız zaman __call sihirli metodu otomatik olarak tetiklenir yani çalışır. Bu metot gördüğünüz gibi 2 farklı parametre ile birlikte çalışır. İlk parametre tanımlanmadan kullanılmaya çalışılan fonksiyonun adını verirken, ikinci parametre bu metodun çağrıldığı an gönderdiği parametrelere erişim için kullanılır. Bu sayede yukarıdaki gibi özel hata mesajları oluşturabilirsiniz. 

Yukarıdaki kodların çıktısı şu şekilde olacaktır:

sifreDegistir adında bir fonksiyon bulunmuyor. 

Çok büyük bir projede çalışıyorsanız ya da yıllar önce oluşturduğunuz bir projeye müdahale etmek istediğinizde bazı metotları tanımladığınızı zannedebilirsiniz. İşte __call metoduyla bu tarz hatalı kullanımları yakalayabilir ve sorunları çözebilirsiniz. 

6. __callStatic

Yukarıda anlattığım __call ile neredeyse aynı işi yapar. __callStatic sihirli metodu, nesne içinde tanımlanmayan static yapıdaki bir fonksiyona erişim esnasında çalışır. Daha önceki yazılarımda static yapıdaki bir fonksiyona nesne oluşturmadan, doğrudan class adıyla erişim sağlandığını açıklamıştım. Yani ClassAdı::FonksiyonAdi yapısıyla, new anahtar kelimesi kullanıp nesne üretmeden, static yapıdaki bir fonksiyona doğrudan erişim sağlayabilirsiniz. İşte __callStatic sihirli metodu da class içerisinde tanıtılmadığı halde bu şekilde static bir fonksiyona erişim sağlanmaya çalışıldığında tetiklenir. Aşağıdaki örneği inceleyelim.


class Daire
{
    static $pi = 3.14;
    
    static function cevreHesapla($r)
    {
        return 2 * self::$pi * $r;
    }

    static function __callStatic($isim, $parametreler)
    {
        echo "$isim adında static bir fonksiyon bulunmamaktadır.";
    }
}

echo Daire::$pi;
echo Daire::cevreHesapla(6);

echo Daire::alanHesapla(3);


Bu örnekte $pi değişkeni ve cevreHesapla fonksiyonu static olarak tanımlanmıştır. Bu iki üyeye doğrudan class adı üzerinden, nesne oluşturmadan erişim sağladık. Ancak Daire class'ı içerisinde dikkat ederseniz alanHesapla adında static bir fonksiyon tanımı yapmadık. İşte tanımlanmayan bu static metoda Daire::alanHesapla(3) şeklinde erişim sağlamaya çalıştığımızda __callStatic metodu çalışacak ve hata metni yazacaktır. __callStatic metodu da __call metodu gibi iki parametre ile çalışır. İlk parametre tanımlanmadan kullanılmaya çalışılan static fonksiyonun adını verirken, ikinci parametre bu metot ile birlikte gönderilen parametreleri yakalar. 
 

7. __unset

unset() fonksiyonu normalde tanımlı olan bir değişkeni, tanımsız yapmaya yani yok etmeye yarar. OOP yapısında yer alan __unset() metodu ise class içerisinde tanımlanmamış ya da erişim yetkisi bulunulmayan (private veya protected) bir özellik yani değişken unset ile yok edilmeye çalışıldığına tetiklenir. __unset() sihirbaz metodu bir parametre ile çalışır. Bu parametre de tanımlanmayan veya erişim yetkisi olmayan özellik yani değişkeni yakalar. Bu sayede __unset() içinde özel hata mesajları oluşturabilirsiniz.

class Araba
{
    public $marka;
    private $fiyat;
    protected $vitesTuru;

    public function __unset($degisken)
    {
        echo "$degisken adında bir özellik bulunmuyor ya da erişim yetkiniz yok.";
    }
}

$araba = new Araba();
$araba->marka = "Hyundai";

unset($araba->marka);       // public olduğu için unset edecektir.

unset($araba->fiyat);       // private olduğu için __unset() metodu çalışacaktır. 
unset($araba->vitesTuru);   // protected olduğu için __unset() metodu çalışacaktır. 

unset($araba->yakitTuru);   // yakitTuru adında bir özellik olmadığı için __unset() metodu çalışacaktır.


Araba class'ı içinde yer alan marka özelliği public olduğu için nesne üzerinden yani class dışından erişim sağlanabilmektedir. Bu sayede hem değer atama işlemi hem de unset ile yok etme işlemi başarılı bir şekilde gerçekleşecektir. Ancak Araba class'ı içinde fiyat ve vitesTuru özellikleri private ve protected olarak tanımlandığı için bu özellikler için unset işlemi hata verecek yani devreye __unset() sihirbaz metodu girecektir. Ayrıca Araba class'u içinde yakitTuru adında bir özellik olmadığı için yine __unset() sihirbaz metodu çalışacaktır. 

Bu kodların çalışması sonucu aşağıdaki hatalar sayfaya yazılacaktır.

fiyat adında bir özellik bulunmuyor ya da erişim yetkiniz yok.
vitesTuru adında bir özellik bulunmuyor ya da erişim yetkiniz yok.
yakitTuru adında bir özellik bulunmuyor ya da erişim yetkiniz yok.


8. __isset

isset() fonksiyonu normalde bir değişkenin tanımlanıp tanımlanmadığını kontrol eder. Eğer değişken tanımlı ise true, değilse false değeri döndürür. __isset() sihirbaz metodu ise, class içerisinde tanımlanmayan ya da erişim yetkisi bulunmayan (private, protected) bir özelliğe yani değişkene isset() fonksiyonu uygulandığında devreye girer. 

class Araba
{
    public $marka;
    private $fiyat;
    protected $vitesTuru;

    public function __isset($degisken)
    {
        echo "$degisken adında bir özellik bulunmuyor ya da erişim yetkiniz yok.";
    }
}

$araba = new Araba();
$araba->marka = "Hyundai";

echo isset($araba->marka);      // public ve tanımlı olduğu için true yani 1 değeri yazar

isset($araba->fiyat);           // private olduğu için __isset() metodu çalışacaktır. 
isset($araba->vitesTuru);       // protected olduğu için __isset() metodu çalışacaktır. 

isset($araba->yakitTuru);       // yakitTuru adında bir özellik olmadığı için __isset() metodu çalışacaktır.

Araba class'ı içerisinde public yapıda $marka adında bir özellik olduğu için isset fonksiyonu çalıştığı zaman 1 yani true değeri dönecektir. Ancak Araba class'ı içinde yer alan fiyat ve vitesTuru özellikleri private ve protected yapıda olduğu için class dışından erişim yetkisi olmayacaktır. Bu durumda isset() fonksiyonu çalıştırıldığı an __isset() sihirbaz metodu devreye girecektir ve özelleştirdiğimiz hata mesajı sayfaya yazılacaktır. Yine aynı şekilde Araba class'ı içinde yakitTuru adında bir özellik (değişken) tanımlı olmadığı için __isset() metodu çalışacaktır. 
 

9. __sleep

Bu sihirli metot, nesneye serialize işlemi uygulandığı an çalışır. O zaman öncelikle serialize işlemini bilmek gerekiyor. Serialize işlemi ile bir dizi, String'e çevrilir. Yani diziye ait elemanlar belli bir mantığa göre String yapıya çevrilir. 

$renkler = array("Kırmızı", "Siyah", "Beyaz");
$stringRenkler = serialize($renkler);
echo $stringRenkler;

Bu örnekte renkler adında bir dizi oluşturup içine 3 tane değer atadım. Daha sonra ise bu diziye serialize işlemi uygulayıp sonucunu da stringRenkler adında bir değişkene atadım. Bu değişkeni ekrana yazdırdığım zaman aşağıdaki gibi bir çıktı elde edeceğim.

a:3:{i:0;s:10:"Kırmızı";i:1;s:5:"Siyah";i:2;s:5:"Beyaz";}

Gördüğünüz gibi, dizimiz belli bir kurala göre string bir yapıya çevrilmiş oldu. 

Şimdi artık __sleep yapısını incelemeye geçebiliriz. Bir nesneye serialize işlemi uygulandığında __sleep sihirbaz metodunun çalıştığını söylemiştik. Yukarıdaki örnekte dikkat ettiyseniz diziye ait tüm elemanlar serialize işlemi sonucunda String yapıya çevrildi. Ancak OOP yapısında bulunan __sleep() sihirli metoduyla nesneye ait hangi değerlerin String yapıya çevrileceğine siz karar verebilirsiniz. Yani diyelim ki bir nesneye ait 4 özellik var. Siz __sleep() sihirli metodu içerisinde bu özelliklerin hangilerinin serialize işlemi sonucunda String'e dönüşeceğine karar verebilirsiniz. Aslında bazı özelliklerin String yapıya dönüştürülmesini engelleyebilirsiniz. 

class Ogrenci
{
    public $adSoyad; 
    public $sinif;
    public $ortalama;

    public function __sleep()
    {
        return array('adSoyad','sinif');
    }
}

$ogrenci = new Ogrenci();
$ogrenci->adSoyad = "Yücel Alkan";
$ogrenci->sinif = 10;
$ogrenci->ortalama = 93.25;

$stringOgrenci = serialize($ogrenci);

echo $stringOgrenci;

Kodlarımızı inceleyelim. Ogrenci sınıfından bir nesne üretip, üç özelliğine değer atadım. Ardında da nesneye serialize işlemi uyguladık. İşte __sleep() sihirli metodu bu esnada çalışacaktır. Dikkat ettiyseniz __sleep() sihirli metodu içinde bir return yapısı bulunuyor. Bu return ifadesi ile adSoyad ve sinif değerlerini içeren bir array yani dizi return edilmiştir. İşte serialize işlemi bu değerlere göre yapılacaktır. Yani sadece adSoyad ve sinif özellikleri String yapıya aktarılacak, ortalam özelliği aktarılmayacaktır. Siz bu şekilde __sleep() sihirli metodu içinde hangi özelliklerin String yapıya aktarılacağına karar verebilirsiniz. 

Örneğimizde oluşturduğumuz $stringOgrenci değişkenini ekrana yazdırdığımız zaman aşağıdaki çıktıyı elde edeceğiz. 

O:7:"Ogrenci":2:{s:7:"adSoyad";s:12:"Yücel Alkan";s:5:"sinif";i:10;}

Çıktıya dikkat edin, $ogrenci nesnesine ait ortalam özelliği String yapı içerisinde yer almıyor. İşte __sleep() sihirli metodu ile bu şekilde nesneye ait bazı özelliklerin String'e aktarılmasını önleyebilirsiniz. 

10. __wakeup

Nesneye unserialize işlemi uygulandığı zamana çalışır. Öncelikle unserialize işleminin mantığını anlamaya çalışalım. Bir önceki maddede serialize işlemini açıklamıştım. Serialize ile bir dizi, String bir yapıya dönüştürülür, demiştim. İşte unserialize işlemi ile de bu String yapı tekrar eski haline yani diziye dönüştürülür. 

$renkler = array("Kırmızı", "Siyah", "Beyaz");
$stringRenkler = serialize($renkler);

echo $stringRenkler;

$renkler = unserialize($stringRenkler);

print_r($renkler);

Yukarıdaki örnekte önce renkler adında bir dizi oluşturup, serialize işlemi uyguladık ve çıkan sonucu stringRenkler değişkenine aktardık. Daha sonra ise String yapıda olan bu değişkene, unserialize işlemi uyguladık ve String yapıyı dizi haline döndürdük. Bu işlemler sonucunda aşağıdaki çıktılar ekrana yazılacaktır. 

a:3:{i:0;s:10:"Kırmızı";i:1;s:5:"Siyah";i:2;s:5:"Beyaz";}

Array ( [0] => Kırmızı [1] => Siyah [2] => Beyaz )


Şimdi artık __wakeup() sihirli metoduna geçebiliriz. İşte __wakeup() sihirli metodu, unserialize işlemi uygulandığında çalışır. Aşağıdaki işlemimizi inceleyelim.

class Ogrenci
{
    public $adSoyad; 
    public $sinif;
    public $ortalama;

    public function __sleep()
    {
        return array('adSoyad','sinif','ortalama');
    }

    public function __wakeup()
    {
        echo "String'e dönüştürülen nesne, tekrar tekrar nesne haline döndürüldü.";
    }
}

$ogrenci = new Ogrenci();
$ogrenci->adSoyad = "Yücel Alkan";
$ogrenci->sinif = 10;
$ogrenci->ortalama = 93.25;

$stringOgrenci = serialize($ogrenci);

$yeniOgrenci = unserialize($stringOgrenci);

print_r($yeniOgrenci);

$ogrenci nesnesine önce serialize işlemi uyguladık ve tüm özelliklerini string yapıya aktardık. Ardında String yapıya unserialize işlemi uyguladık ve bu yapıyı tekrar eski haline döndürdük. İşte __wakeup tam olarak bu unserialize işlemi esnasında çalışacaktır. Yukarıdaki işlemlerin ekran çıktısı aşağıdaki gibidir. 
 

String'e dönüştürülen nesne, tekrar tekrar nesne haline döndürüldü.

Ogrenci Object ( [adSoyad] => Yücel Alkan [sinif] => 10 [ortalama] => 93.25 )


 

11. __toString

Bu sihirbaz metot, oluşturulan nesne print veya echo gibi bir komutla ekrana yazdırıldığı an çalışır. Bu metot içerisinden String yapıda bir değeri return ettirmeniz gerekiyor. Aksi takdirde hata alacaksınız.

class Kitap
{
    public $kitapAdi;

    public function __toString()
    {
        return "Oluşturulan nesne ekrana yazdırıldı";
    }
}

$kitap = new Kitap();
echo $kitap;

Yukarıdaki örnekte Kitap sınıfından $kitap adında bir nesne üretip, echo komutu ile bu nesneyi doğrudan ekrana yazdırdık. İşte tam da bu yazdırma işi esnasında __toString() metodu tetiklenecek ve içerisinde tanımlanana işlemler yapılacaktır. Bu kodların ekran çıktısı şu şekilde olacaktır. 

Oluşturulan nesne ekrana yazdırıldı.

Bu örneği daha güzel ve işlevsel bir hale getirebiliriz. __toString() metodu içerisinde, bu metodun ait olduğu class adını da yazdırabiliriz. Aşağıdaki örneği inceleyelim. 

class Kitap
{
    public $kitapAdi;

    public function __toString()
    {
        return get_class($this)." sınıfından bir nesne ekrana yazdırıldı";
    }
}

$kitap = new Kitap();
echo $kitap;

get_class() fonksiyonu, herhangi bir yapının Class adını döndürmektedir. Yani bu örnekte Kitap ifadesini döndürecektir. Bu kodların ekran çıktısı aşağıdaki gibi olacaktır. 

Kitap sınıfından bir nesne ekrana yazdırıldı

12. __debugInfo

Oluşturulan nesne, var_dump() fonksiyonu ile ekrana yazdırıldığı an çalışan fonksiyondur. Normalde var_dump() fonksiyonu, bir nesneye ait tüm özellikleri ekrana yazdırır. Siz __debugInfo() sihirli metodunu kullanarak bu yapıyı özelleştirebilir ve istediğiniz özelliklerin ekrana yazdırılmasını sağlayabilirsiniz. __debugInfo() sihirli metodundan bir array return etmeniz gerekiyor. Bu array içine istediğiniz bilgileri atayabilirsiniz. 

class Kitap
{
    public $kitapAdi;
    public $yazar;
    public $fiyat;

    public function __construct($getKitapAdi, $getYazar, $getFiyat)
    {
        $this->kitapAdi = $getKitapAdi;
        $this->yazar = $getYazar;
        $this->fiyat = $getFiyat;
    }

    public function __debugInfo()
    {
        return array( 
            "Kitap Adı" => $this->kitapAdi,
            "Yazar" => $this->yazar,
            "Fiyat" => $this->fiyat
        );
    }
}

$kitap = new Kitap("Kalplerin Keşfi", "İmam Gazali", 25);

var_dump($kitap);

Yukarıdaki örnekte, Kitap sınıfından $kitap adında bir nesne üretip, __construct() metodunu kullanarak tüm bilgileri bu nesneye atamış oldum. Ardından da var_dump ile bu nesneyi ekrana bastırdım. Tabi ki burada tüm özellikleri göndermek zorunda değilsiniz. Hatta farklı bilgileri bile gönderebilirsiniz. Yukarıdaki kodların ekran çıktısı aşağıdaki gibi olacaktır. 

object(Kitap)#1 (3) { ["Kitap Adı"]=> string(16) "Kalplerin Keşfi" ["Yazar"]=> string(12) "İmam Gazali" ["Fiyat"]=> int(25) }

13. __clone

PHP OOP yapısında clone() fonksiyonu ile herhangi bir nesneyi birebir kopyalamak yani klonlamak mümkündür. Bu durumda klonlanan nesne ile aynı özelliklere sahip yeni bir nesne oluşacaktır. İşte class içerisinde tanımlanan __clone() sihirbaz metodu bu durumda çalışacaktır. Yani __clone() sihirbaz metodu bir nesne kopyalandığı zaman çalışır diyebiliriz.

class Ogrenci
{
    public $adSoyad;
    public $ortalama;

    public function __construct($getAdSoyad, $getOrtalama)
    {
        $this->adSoyad = $getAdSoyad;
        $this->ortalama = $getOrtalama;
    }

    public function __clone()
    {
        echo "Nesne Kopyalandı";
    }
}

$ogrenci = new Ogrenci("Barış Manço", 95);
$ogrenci2= clone($ogrenci);

Dikkat ettiyseniz $ogrenci adında bir nesne oluşturup, özelliklerini __construct() sihirbaz metoduna göndererek özelliklerini belirledim. Ardından clone() fonksiyonu ile $ogrenci nesnesini klonlayıp $ogrenci2 adında yeni bir nesne oluşturdum. İşte class içerisinde bulunan __clone() sihirbaz metodu tam da bu esnada çalışacak ve burada yazılan komutları işleme alacaktır. Bu işlemler sonucunda $ogrenci ile $ogrenci2 nesneleri birebir aynı özelliklere sahip olacaktır. Ayrıca nesne klonlandığı esnada __clone() fonksiyonu çalıştığı için ekrana "Nesne Kopyalandı" şeklinde bir uyarı verilecektir. 
 

14. __invoke

PHP Object Oriented Programming yapısında bir nesneyi fonksiyon gibi çalıştırmak mümkündür. İşte __invoke() sihirbaz metodu tam da bu durumda çalışacaktır. Aşağıdaki örneği inceleyelim. 

class Sanatci
{
    public $adSoyad;
    public $dogumYeri;

    public function __construct($getAdSoyad, $getDogumYeri)
    {
        $this->adSoyad = $getAdSoyad;
        $this->dogumYeri = $getDogumYeri;
    }

    public function __invoke($veri)
    {
        echo $veri." adında bir değer geldi";
    }
}

$sanatci = new Sanatci("Barış Manço", "İstanbul");
$sanatci(5);

Dikkat ederseniz Sanatci class'ından $sanatci adında bir nesne üretip, bu nesneyi fonksiyon gibi kullandık. Normalde nesneye ait bir özelliğe erişmek için $nesne->ozellikAdi, fonksiyona erişmek için $nesne->fonksiyonAdi() şeklinde bir yapı kullanıyoruz. Ancak burada nesneyi doğrudan bir fonksiyonmuş gibi kullanıp, parametre göndererek __invoke() sihirbaz metodu içerisinde istenilen işlemi yapmak mümkündür. Pratik bur kullanımı vardır. 

15. __setState

Oluşturulan bir nesnenin herhangi bir özelliğine var_export() fonksiyonu uygulandığı an çalışan sihirli metottur. var_export() fonksiyonu, bir değişkenin yapısı hakkında bilgi veren veya bu değişkenin çıktısını veren fonksiyondur. Eğer var_export() fonksiyonuna parametre olarak true değerini gönderirseniz, çalıştırılabilir PHP kodu döndürecektir. Daha sonra dönüştürdüğünüz bu PHP kodunu, eval() fonksiyonu ile çalıştırabilirsiniz. Aşağıdaki örneğimizi inceleyelim.

class Ogrenci
{
    public $adSoyad;
    public $ortalama;

    public function __set_state($ozellik)
    {
        echo "Nesneye ait __set_state fonksiyonu çalıştı";
    }
}

$ogrenci = new Ogrenci();
$ogrenci->adSoyad = "Yücel Alkan";
$ogrenci->ortalama = 93.75;

eval(var_export($ogrenci, true).";");

Örneğimizde $ogrenci adında bir nesne oluşturup, iki özelliğini girdik. Ardından bu nesneyi, true parametresi ile birlikte var_export() fonksiyonuna gönderdik. İşte bu esnada __set_state sihirli metodu çalışacaktır. 

Eğer true parametresi göndermeseydik, $ogrenci nesnesi hakkında bilgi dönecekti. Ancak bu durumda __set_state sihirli metodu çalışmayacakt ve çıktı aşağıdaki gibi olacaktı.

Ogrenci::__set_state(array( 'adSoyad' => 'Yücel Alkan', 'ortalama' => 93.75, ))

* * *

PHP Object Oriented Programming yapısında sihirli metodların kullanımı bu şekilde. 

Soru ve görüşlerinizi yorum olarak belirtebilirsiniz. Hayırlı çalışmalar dilerim.

07.06.2020
24940
Yorumlar
Bu içeriğe henüz yorum yapılmamıştır. İlk yorum yapan siz olun!
Yorum Yapın