Burhan T. 4 dakikalık okuma
June 17, 2017

PHP’de Trait olayını derinlemesine inceleyelim.

3N sorumuzu sorarak Trait kavramını irdelemeye başlayalım:

  1. PHP’de Trait nedir ?
  2. PHP’de neden Trait kullanmaya ihtiyaç duyarız ve neden dile girmiştir ?
  3. PHP’de Trait nasıl kullanılır ?

1. TRAİT NEDİR ?

Sınıfların kabiliyetini genişletmeye yarar. Traitler aynen sınıf oluşturmadaki gibi kullanılır ama class yerine trait kelimesini kullanırız:

trait Ev_ic_dekorasyon{
    function icrenk(){
        echo "sarı";
        }
    }
trait Ev_dis_dekorasyon{
    function disrenk(){
        echo "beyaz";
        }
    }
class ev{
    use Ev_ic_dekorasyon, Ev_dis_dekorasyon;
    }
$evolustur = new ev;
$test->icrenk();
$test->disrenk();

2. PHP’DE NEDEN TRAİT KULLANMAYA İHTİYAÇ DUYARIZ VE NEDEN DİLE GİRMİŞTİR ?

Bazen yazdığımız bir metodu, başka sınıflar içerisinde tekrar tekrar yazmaya gerek yok. Ne olacak peki ? Trait’ler yardımımıza yetişiyor. Oluşturduğumuz bir trait’i sınıflar içinde use ile dahil ederek kullanıyoruz. Böylece 1 kez kullanmış oluyoruz. Aşağıdaki örnekte bunu gösterelim:

class mysql{
    function checkdb(){
        echo "..";
        }
    }
class mssql{
    function checkdb(){
        echo "...";
        }
    }
//Yukarıdaki yapıyı şu hale getirelim:

trait DbTrait {
    function checkdb(){
        echo "...";
        }
}

class mysql{

    use DbTrait;

    $this->checkdb();

    }


    class mssql{

        use DbTrait;
         $this->checkdb();
    }

Şimdi dikkat! PHP’de oluşturduğumuz bir sınıfı 2 sınıftan türetme yapamayız. Sadece 1 sınıf olmalı. Böyle bir sınırlama vardır. Şöyle:

class Ev_ic_dekorasyon{
    function icrenk(){
        echo "sarı";
        }
    }
class Ev_dis_dekorasyon{
    function disrenk(){
        echo "beyaz";
        }
    }




//Aşağıdaki kod çalışacak. Çünkü 1 sınıftan türetme yapıyorum.
class Ev extends Ev_ic_dekorasyon {

    }

//Aşağıdaki kod çalışmayacak. Fatal error. Çünkü 2 sınıftan türetme yapamayız.
// işte bunu aşmak için trait hadisesi PHP diline girmiş durumda...
class ev extends Ev_ic_dekorasyon,  Ev_dis_dekorasyon{

    }

Bu yukarıdaki yazdığım durumlardan dolayı PHP diline Trait özelliği girmiştir.

3. PHP’DE TRAİT NASIL KULLANILIR ?

Trait aynı sınıf tanımlama gibi yapılıyor ama class yerine trait kelimesiyle. Sınıf içerisinde kullanımı da use anahtar kelimesi ile oluyor. Ne extends ne de implements ile bir şey yapıyorum. Onlarla işim yok. Böylece oluşturduğum sınıf içinde birden çok traiti tanımlayarak bir sınıfa dahil edip (türetme oluyor) kullanabilirim.

trait Ev_ic_dekorasyon{
    function icrenk(){
        echo "sarı";
        }
    }
trait Ev_dis_dekorasyon{


    function disrenk(){
        echo "beyaz";
        }
    }
class Ev{

    use Ev_dis_dekorasyon, Ev_ic_dekorasyonu;

 }

$evolustur = new Ev;
$test->icrenk();
$test->disrenk();

Trait’lerin en önemli özelliği self ve parent reserved word kelimelerinin kullanılmasıdır.

Self için örnek verelim:

trait Kitap_copyright{

    function yazar($yazar){

        echo 'Telif hakkı 2016 '.$yazar;

        }

    }

trait Kitap_sayfadizayni {

    use Kitap_copyright;

    function dizayn1(){

        self::yazar('Burhan');

        echo "Dizayn için gerekli kodları farzedin...";

        }

    }


class Kitap{

    use Kitap_sayfadizayni; //sadece kitap_sayfadizayni kullanıldı. kitap_copyright, kitap_sayfadizayni içinde kullanılmıştı.
    }

$kitabim1 = new Kitap;
$kitabim1->dizayn1();

Trait’lerde parent self’den biraz daha farklı. Aşağıdaki örnekte yukarıdakinin parent için modifiye edilmiş hali:

//Dikkat edin Kitap_copyright bir class. Bir trait değil. İşte parent ile bu sınıfın metoduna erişeceğim 🙂
class Kitap_copyright{

    function yazar($yazar){

        echo 'Telif hakkı 2016 '.$yazar;

        }

    }

trait Kitap_sayfadizayni {



    function dizayn1(){

        parent::yazar('Burhan'); // bu yazar fonksiyonu trait içinde değil. Class içinde bir metod.

        echo "Dizayn için gerekli kodları farzedin...";

        }

    }


class Kitap extends Kitap_copyright{

    use  Kitap_sayfadizayni;



    }

$kitabim1 = new Kitap;
$kitabim1->dizayn1();

parent kullandığım metod, trait içinde tanımlı bir fonksiyon değil. Class içinde tanımlı bir fonksiyon. Trait içinde class’ta tanımlı bir fonksiyonu parent ile çağırabiliyorum. İşte yukarıdaki örneği iyi inceleyerek bunu anlayabilirsiniz.

TRAİT’LERDE İNSTEAD OF OPERATÖRÜNÜN KULLANIMI:

Bir den fazla Triat’ınız var diyelim. İkisinde de aynı isimde fonksiyonlar var diyelim. insteadof operatoru ile bunların birisini kullanabilirsiniz.

Burada dikkat etmeniz gereken önemli bir konu var. Önceki örneklerde use bir, iki. şeklinde kullanıyorduk. Ama insteadof kullanacaksanız use bir, iki {} yapmalısınız.

// Bu örnek Adil İlhan'ın katkısıdır.

trait Araba{
    function Marka(){
        echo "Mercedes";
    }
}
trait Otomobil{
    function Marka(){
        echo "Fiat";
    }
}
class Arac{
    use Araba, Otomobil{
        Araba::Marka insteadof Otomobil;
    }
}
$bilgi = new Arac;
$bilgi->Marka();

Aynı isimde fonksiyona sahip iki Trait’den birisini kullandıktan sonra, as ile fonksiyon ismi değiştirilebilir.

// Bu örnek Adil İlhan'ın katkısıdır.
trait Araba{
function Marka(){
    echo "Mercedes";
    }
}
trait Otomobil{
    function Marka(){
        echo "Fiat";
    }
}
class Arac{
    use Araba, Otomobil{
        Araba::Marka insteadof Otomobil;
        Otomobil::Marka as Yeni;
    }
}
$bilgi = new Arac;
$bilgi->Marka();
$bilgi->Yeni();

Trait’deki bir değişkene de erişebilirsiniz:

trait Blog{
    public $title = "my blog";
}
class anaSitem{
    use Blog;
}
$web = new anaSitem;
echo $web->title;

Trait’lerde private bir fonksiyona class içinde nasıl ulaşabiliriz: 2 yöntem var.

//Bu örnek Adil İlhan'ın katkısıdır.

trait Araba{
    private function Marka(){
        echo "BMW ";
    }
    private function Model(){
        echo "M3";
    }
}
// 1. yöntem
class Bilgi{
    use Araba;
    function Galeri(){
        self::Marka();
    }
}
class Test extends Bilgi{
    //2. yöntem
    use Araba{
        Model as public YeniModel;/*Model() fonksiyonu public visibility de YeniModel fonksiyonu oldu.
Eğer bir fonksiyonun visibility ayarını değiştirecekseniz, yeni isim vermelisiniz.*/
    }
}
$obj = new Bilgi;
$obj->Galeri();
$yeni = new Test;
$yeni->YeniModel();

Etiketler: