BG MVC Model View Controller eğitim serisi yayında...

Ana sayfa > Programlama > PHP > PHP sınıflar

PHP sınıflar

PHP'de sınıf içinde aynı veya farklı veri türünden sabit ve değişkenlerle, bu sabit ve değişkenleri kullanan ve işlem yapan fonksiyonlardan oluşan bir yapıdır. Sınıf içinde yer alan değişkenler özellik (property), fonksiyonlar ise metod (method) olarakta adlandırılır. Temel sınıf bildirimi class anahtar kelimesi ve peşinden gelen sınıf adı ile başlar. Daha sonra, sınıf sabit ve değişkenleri ile fonksiyon tanımlamalarının arasında yer aldığı { } parentezleri kullanılır. Geçerli bir sınıf adı bir harf veya alt çizgi ile başlar ve herhangi bir sayıda harf, sayı veya alt çizgilerle devam eder.

Aynı anda birden fazla farklı veri türünü ve fonksiyon tanımlamalarını da barındırabilen sınıf adı altında oluşturulan nesne (object) veri türü ile tüm sınıf içeriğine ulaşabilir ve işlem yapabiliriz.

Sınıf tanımlaması

Sınıf tanımlaması aşağıdaki şekilde yapılır:


class sınıf_adı
{
    public $deg_adi = 'öntanımlı değer'; // değişken (property) bildirimi
   
    // fonksiyon (method) bildirimi
    public function fonksiyon_adı()
    {
        fonksiyon komut satırı;
        .
        .
        fonksiyon komut satırı;	 
    }
}


class personel
{
    public $adi;    // String değişken
    public $soyadi; // String değişken
    public $yasi;   // Integer değişken
	
    public function yaz_bilgi()
    {
        echo $this -> adi . " " . $this -> soyadi . " " . $this -> yasi . '<br/>';
    }
}

Yukarıdaki sınıf yapısı içinde iki adet string ve bir adet integer değişken ile sınıf içindeki verileri ekrana yazdırmaya yarayan bir fonksiyon tanımladık.

$this değişkeni ve -> işlemcisi

Sınıf içindeki bir fonksiyondan bir veri değişkenine erişim için $this-> ifadesi kullanılmaktadır.

Sınıf yapısı içinde veri atamak için tanımlanan değişken adlarının $ işareti ile başladığına, ancak değişkene erişim için değişken adının başındaki $ işaretinin kullanılmadığına dikkat ediniz!

Sınıf yapısına ait nesne veri türünü tanımladığımızda, ilgili sınıf yapısının tüm verilerine tanımladığımız nesne veri türü yoluyla ulaşabiliriz. Nesne veri türü tanımlamak için new ifadesi kullanılır. Böylelikle sınıf yapısının bir kopyasını oluşturmuş oluruz.

new anahtar kelimesi

$nesne_adı = new sınıf_adı();

Tanımlanan nesnenin sınıf içindeki veri değişkenlerine erişimi için -> işlemcisi kullanılır.


$obj_per = new personel();

$obj_per->adi = "Mehmet";      // nesne verisi yoluyla sınıf değişkenine değer atama
$obj_per->soyadi = "Çalışkan"; // nesne verisi yoluyla sınıf değişkenine değer atama
$obj_per->yasi = 25;           // nesne verisi yoluyla sınıf değişkenine değer atama

$obj_per->yaz_bilgi();         // nesne verilerini ekrana yazar.


<html>
<body>

<?php
    class personel
    {
        public $adi;          
        public $soyadi;       
        public $yasi;         
	
        public function  yaz_bilgi()
        {
            echo $this->adi . " " . $this->soyadi . " " . $this->yasi . '<br/>';
        }
    }

    $obj_per01 = new personel();
    $obj_per02 = new personel();

    $obj_per01->adi = "Mehmet";       
    $obj_per01->soyadi = "Çalışkan";  
    $obj_per01->yasi = 25;            

    $obj_per02->adi = "Selami";       
    $obj_per02->soyadi = "Yalçın";  
    $obj_per02->yasi = 32;

    $obj_per01->yaz_bilgi();
    $obj_per02->yaz_bilgi();
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

Mehmet Çalışkan 25
Selami Yalçın 32

Yukarıdaki PHP dosyasında, personel adlı sınıf yapısından iki adet nesne verisi tanımlanır. Nesne verilerine farklı değerler atanarak ekrana yazılır.

new anahtar kelimesi ile bir sınıf yapısına ait bir nesne oluşturduktan sonra, bu değişkeni başka bir değişkene atayarak, atama yaptığımız değişkenin sınıf içindeki verilere ulaşmasını sağlayabiliriz.


<html>
<body>

<?php
    class personel
    {
        public $adi;          
    }

    $obj_per01 = new personel();

    $obj_per01->adi = "Ahmet";       

    $obj_per02 = $obj_per01;
    $obj_per03 = &$obj_per01;

    echo $obj_per01->adi . "<br/>"; 

    $obj_per02->adi = "Mehmet";       
    echo $obj_per02->adi . "<br/>";  

    $obj_per03->adi = "Murat";       
    echo $obj_per03->adi . " " . $obj_per01->adi;
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

Ahmet
Mehmet
Murat Murat

Yukarıdaki PHP dosyasında, önce $obj_per01 adlı bir nesne oluşturulur. Bu nesne ile sınıf içindeki $adi değişkenine bir değer atanır. Sonra, $obj_per01 değişkeni değer yoluyla $obj_per02 değişkenine ve referans yoluyla $obj_per03 değişkenine atanır. $obj_per02 değişkenine yapılan atama ile farklı bir kopya oluşturulumuş olur, ancak $obj_per03 yapılan atama ile sadece mevcut kopyanın adresi geçirilmiş olur. Bu nedenle, $obj_per03 ile yapılan değişiklik $obj_per01 değerini etkiler.

Nesne kalıtımı ve extends anahtar kelimesi

Kalıtımı bir sınıfın üst sınıftan miras alması olarak ifade edebiliriz. PHP'de kalıtım nesne verisi ile birlikte kullanılır.

Bir sınıftan diğer bir sınıf türetildiğinde, alt sınıf üst snıfta yer alan tüm public ve protected yöntemleri kendisine dahil eder (miras alır). Dahil edilen yöntemler, aynı isim ile yeniden bildirimi yapılarak geçersiz hale getirilmedği sürece, tüm özelliklerini korurlar.

Kalıtım özelliği için bir sınıf tanımlamasında extends anahtar kelimesi kullanılarak başka bir sınıf içinde yer alan değişken ve fonksiyonların tamamının yeni tanımlanan sınıf içinde otomatik olarak yer alması sağlanır. Bir sınıf sadece tek bir sınıf içeriğini dahil edebilir.

  • Otomatik yükleme kullanılmadığı sürece, snıflar kullanılmadan önce tanımlanmalıdır.
  • Bir sınıftan diğer bir sınıf türetildiğinde üst sınıf alt sınıftan önce tanımlanmalıdır.

Üst (parent) sınıf içinde yer alan fonksiyon ve değişkenler üst sınıf içindeki aynı isimle yeniden tanımlanarak geçersiz hale getirilebilir. Ancak, üst sınıf içinde final olarak tanımlanmış fonksiyonlar geçersiz hale getirilemez. parent:: ifadesi kullanılarak üst sınıfın geçersiz hale getirilmiş fonksiyon ve değişkenlerine erişim sağlanabilir.


<html>
<body>

<?php
    class personel
    {
        public $adi;          
        public $soyadi;       
        public $yasi;         
	
        public function yaz_bilgi()
        {
            echo $this->adi . " " . $this->soyadi . " " . $this->yasi . '<br/>';
        }
    }

    class per_detay extends personel
    {
        public $baba_adi;          
        public $anne_adi;       
        public $memleket;         
	
        // Üst snıf içindeki fonksiyonun yeniden bildirimi
        public function yaz_bilgi()
        {
            // Geçersiz hale getirilmiş üst sınıf fonksiyonuna erişim
            parent::yaz_bilgi();
            echo $this->baba_adi . " " . $this->anne_adi . " " . $this->memleket;
            echo '<br/>';
        }
    }

    $obj_per = new per_detay();

    $obj_per->adi = "Mehmet";       
    $obj_per->soyadi = "Çalışkan";  
    $obj_per->yasi = 25;            

    $obj_per->baba_adi = "Veli";       
    $obj_per->anne_adi = "Ayşe";  
    $obj_per->memleket = "Ankara";            

    $obj_per->yaz_bilgi();
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

Mehmet Çalışkan 25
Veli Ayşe Ankara

Yukarıdaki PHP dosyasında, personel adlı bir sınıf ve sınıftan türetilen per_detay adlı bir sınıf oluşturulur. personel sınıfı içinde yer alan tüm değişken ve fonksiyonlar per_detay sınıfına aktarıldığından, per_detay sınıfı için tanımlanan nesne ile hem üst sınıf hem de alt sınıf içinde yer alan değişkenlere değer atanır. Üst sınıf içinde yer alan yaz_bilgi() fonksiyonu alt snıf içinde aynı isimle yeniden tanımlandığından geçersiz hale getirilir. Ayrıca, üst sınıf içinde geçersiz hale getirilmiş yaz_bilgi() fonksiyonu parent:: ifadesi kullanılarak çağrılır.

Özellikler (Sınıf değişkenleri)

Bir sınıf içinde yer alan değişkenlere "özellikler" adı verilir. Özellikler, normal değişken bildiriminin önüne public, protected veya private anahtar kelimelerinden biri getirilerek tanımlanır. Bu bildirimlerde, sadece sabit bir değerle ilk değer verme işlemi yapılabilir.

static olarak tanımlanmış özelliklere sınıf yöntemleri içinden erişim için self::$özellik yapısı, static olmayan özelliklere erişim için ise $this->özellik yapısı kullanılır.

Sınıf yöntemleri bir nesne üzerinden çağrıldığında $this sözde değişkeni sınıf yöntemleri içinde de kullanılabilir. Sınıf için oluşturulmuş olan nesnenin referans değeri $this değişkenine geçirilmiştir.


<html>
<body>

<?php
    class personel
    {
        public $deg01; // Öntanımsız özellik bildirimi
        public $deg02 = 24; // Öntanımlı özellik bildirimi
        public $deg03 = "Özellik bildirimi"; // Öntanımlı özellik bildirimi
	  
        // Yorumsuz metin yöntemiyle öntanımlı özellik bildirimi
        public $deg04 = <<< 'YMT'
        Yorumsuz metin yöntemiyle özellik bildirimi
YMT;
        public function yaz_bilgi()
        {
            echo $this->deg01 . " " . $this->deg02 . " ";
            echo $this->deg03 . " " . $this->deg04;
            echo '<br/>';
        }
    }

    $obj_per = new personel();

    $obj_per->deg01 = "Mehmet";       

    $obj_per->yaz_bilgi();   
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

Mehmet 24 Özellik bildirimi Yorumsuz metin yöntemiyle özellik bildirimi

Sınıf sabitleri

Her sınıf için kendine ait sabit değerler tanımlanabilir. Bu sabit değerler aynı kalır ve değiştirilemez. Sabit tanımlamaları ve kullanımlarında $ işareti kullanılmaz. Sabit değerleri sabit bir ifade olmalıdır.


<html>
<body>

<?php
    class personel
    {
        const sabit01 = "Sabit değer 1"; // Sabit bildirimi
	  
        // Yorumsuz metin yöntemiyle sabit bildirimi
        const sabit02 = <<< 'YMT'
        Sabit değer 2
YMT;

        public function yaz_bilgi_self()
        {
            echo self::sabit01 . " " . self::sabit02 . '<br/>'; 
        }

        public function yaz_bilgi_this()
        {
            echo $this->sabit01 . " " . $this->sabit02 . '<br/>'; 
        }
    }

    // sınıf adı ve :: işlemcisi yoluyla
    echo personel::sabit01 . " " . personel::sabit02 . '<br/>';
   
    // Sınıf adının bir değişkene atanması yoluyla (PHP 5.3.0'dan itibaren)
    $sinifadi = "personel";
    echo $sinifadi::sabit01 . " " . $sinifadi::sabit02 . '<br/>'; 

    $obj_per = new personel();

    // Nesne ve :: işlemcisi yoluyla (PHP 5.3.0'dan itibaren)
    echo $obj_per::sabit01 . " " . $obj_per::sabit02 . '<br/>';
   
    $obj_per->yaz_bilgi_self(); // self deyimi ve :: işlemcisi yoluyla
    $obj_per->yaz_bilgi_this(); // $this değişkeni yoluyla   
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

Sabit değer 1 Sabit değer 2
Sabit değer 1 Sabit değer 2
Sabit değer 1 Sabit değer 2
Sabit değer 1 Sabit değer 2

Yukarıdaki PHP dosyasında, sınıf içinde tanımlanan iki farklı sabit değer, dört farklı yöntemle ekrana yazılır.

Sınıfları otomatik yükleme

Nesneye yönelik uygulamalar yazan geliştiriciler tanımladıkları her sınıf için bir dosya oluştururlar. Bu dosyalar, gerekli oldukları PHP dosyalarının başına include() veya require() deyimleri ile tek tek dahil edilirler.

PHP 5 sürümü ile birlikte, her dosyanın başında dahil etme işlemleri yapmak yerine, henüz tanımlanmamış bir sınıfı kullanmak istediğinizde otomatik olarak çağrılan __autoload fonksiyonu tanımlayarak aynı işlemi gerçekleştirebilirsiniz.


// deneme.php, personel.php ve musteri.php dosyaları aynı dizinde olmalıdır!

// personel.php
<?php
    class personel
    {
        public $adi;          
        public $soyadi;       
        public $yasi;         
	
        public function yaz_bilgi()
        {
            echo $this->adi . " " . $this->soyadi . " " . $this->yasi . '<br/>';
        }
    }
?>

// musteri.php
<?php
    class musteri
    {
        public $adi;          
        public $soyadi;       
        public $sirket_adi;         

        public function yaz_bilgi()
        {
            echo $this->adi . " " . $this->soyadi . " " . $this->sirket_adi . '<br/>';
        }
    }
?>

// deneme.php
<html>
<body>

<?php
    function __autoload ($sinif_adi)
    {
        include $sinif_adi . '.php';
    }
   
    // Aşağıdaki her iki satırda nesne tanımlanması yoluyla 
    // __autoload fonksiyonunun çalışmasını sağlar.

    // Sınıf adı __autoload fonksiyonuna değer olarak geçirilir.
    $obj_per = new personel(); 
    
    // Sınıf adı __autoload fonksiyonuna değer olarak geçirilir.
    $obj_musteri = new musteri(); 

    $obj_per->adi = "Ahmet";       
    $obj_per->soyadi = "Saygılı";  
    $obj_per->yasi = 25;            

    $obj_musteri->adi = "Mehmet";       
    $obj_musteri->soyadi = "Güvener";  
    $obj_musteri->sirket_adi = "Güvener Gıda";            
   
    $obj_per->yaz_bilgi();
    $obj_musteri->yaz_bilgi();
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

Ahmet Saygılı 25
Mehmet Güvener Güvener Gıda

Constructors ve Destructors

Constructor

Bir sınıf için oluşturulan nesne kapsamında ilk değer atama işlemlerini gerçekleştirmek amacıyla her sınıf tanımlaması içinde bir constructor yöntemi (fonksiyon) oluşturabilirsiniz.

void __construct ([ mixed $args [, $... ]] )

Eğer alt sınıf içinde bir constructor tanımlanmışsa, üst sınıf içindeki constructor çağrılmaz. Üst sınıf constructor yöntemini çağırmak için parent::__construct() ifadesi kullanılmalıdır.


<html>
<body>

<?php
    class personel
    {
        public $adi;          
        public $soyadi;       
        public $yasi;         

        function __construct ($arg01, $arg02, $arg03)
        {
            $this->adi = $arg01;       
            $this->soyadi = $arg02;  
            $this->yasi = $arg03; 
        }
   
        public function yaz_bilgi()
        {
            echo $this->adi . " " . $this->soyadi . " " . $this->yasi . '<br/>';
        }
    }

    class per_detay extends personel
    {
        public $baba_adi;          
        public $anne_adi;       
        public $memleket;         
	
        function  __construct ($argpar01, $argpar02, $argpar03, $arg01, $arg02, $arg03)
        {
            // Üst sınıf constructor fonksiyonuna erişim
            parent::__construct($argpar01, $argpar02, $argpar03); 
	  
            $this->baba_adi = $arg01;       
            $this->anne_adi = $arg02;  
            $this->memleket = $arg03; 
        }
   
        // Üst snıf içindeki fonksiyonun yeniden bildirimi
        public function yaz_bilgi()
        {
            // Geçersiz hale getirilmiş üst sınıf fonksiyonuna erişim
            parent::yaz_bilgi();
            echo $this->baba_adi . " " . $this->anne_adi . " " . $this->memleket;
            echo '<br/>';
        }
    }

    $obj_per = new per_detay("Ahmet", "Saygılı", "27", "Veli", "Ayşe", "Ankara");

    $obj_per->yaz_bilgi();
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

Ahmet Saygılı 27
Veli Ayşe Ankara

Yukarıdaki PHP dosyasında, sınıf için bir nesne tanımlanırken, constructor fonksiyonları kullanılarak, üst ve alt sınıf özellik değerleri ilk değer atama yoluyla verilir.

Destructor

Bir sınıf için oluşturulan nesne ile ilgili tüm referanslar kaldırıldığı veya nesne yok edildiği zaman destructor yöntemi (fonksiyonu) çağrılır.

void __destruct (void)

Eğer alt sınıf içinde bir destructor tanımlanmışsa, üst sınıf içindeki constructor çağrılmaz. Üst sınıf destructor yöntemini çağırmak için parent::__destruct() ifadesi kullanılmalıdır.


<html>
<body>

<?php
    class personel
    {
        public $adi;          
        public $soyadi;       
        public $yasi;         

        function __construct ($arg01, $arg02, $arg03)
        {
            $this->adi = $arg01;       
            $this->soyadi = $arg02;  
            $this->yasi = $arg03; 
        }

        function __destruct()
        {
            echo 'Destructor fonksiyonu içi' . '<br/>';
        }
   
        public function yaz_bilgi()
        {
            echo $this->adi . " " . $this->soyadi . " " . $this->yasi . '<br/>';
        }
    }

    $obj_per = new personel("Ahmet", "Saygılı", "27");

    $obj_per->yaz_bilgi();

    unset($obj_per);
?>

</body>
</html>


Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

Ahmet Saygılı 27
Destructor fonksiyonu içi

Yukarıdaki PHP dosyasında, dosya sonu geldiğinde nesne yok olduğundan destructor fonksiyonu çağrılır.

Görünürlük

Bir özelliğin ya da bir yöntemin görünürlüğü, bildirimin önüne public, protected ya da private anahtar kelimelerinden biri getirilerek belirlenir. Görünürlük sınıf elemanlarına erişim yetkilerini gösteren kuralları belirler.

  • public olarak bildirilen sınıf elemanlarına (özellik ve yöntemlere) sınıf için tanımlanan bir nesne ile -> işlemcisi kullanılarak direk olarak erişilebilir.
  • protected olarak bildirilen sınıf elemanlarına üst ve alt sınıf ile sınıfın kendi içindeki yöntemler yoluyla erişilebilir.
  • private olarak bildirilen sınıf elemanlarına ise sadece tanımlanmanın yapıldığı sınıf içindeki yöntemler yoluyla erişilebilir.

Özelliklerin görünürlüğü

Sınıf özellikleri public, private, veya protected olarak tanımlanmalıdır. var deyimi ile birlikte yapılan tanımlamalar public olarak kabul edilir.

Sınıf yöntemleri public, private, veya protected olarak tanımlanabilir. Görünürlük kelimerinden herhangi birisi kullanılmadan yapılan tanımlamalar public olarak kabul edilir.


<html>
<body>

<?php
    class bizim_sinif
    {
        public $pub_deg;          
        protected $pro_deg;       
        private $pri_deg;    

        function __construct ($arg01, $arg02, $arg03)
        {
            $this->pub_deg = $arg01;       
            $this->pro_deg = $arg02;  
            $this->pri_deg = $arg03; 
        }   

        public function pub_fonk()
        {
            echo $this->pri_deg . '<br/>';
        }
    }

    class bizim_sinif_alt extends bizim_sinif
    {
        public $pub_alt_deg;          
        protected $pro_alt_deg;       
        private $pri_alt_deg;         

        private $pri_top_deg;         
   
        function __construct ($argpar01, $argpar02, $argpar03, $arg01, $arg02, $arg03)
        {
            parent::__construct ($argpar01, $argpar02, $argpar03);
            $this->pub_alt_deg = $arg01;       
            $this->pro_alt_deg = $arg02;  
            $this->pri_alt_deg = $arg03;
        } 
   
        public function pub_alt_fonk01()
        {
            echo $this->pub_deg . " "; 
            echo $this->pro_deg . " "; 
            echo $this->pri_deg . " "; // Bu satır herhangi bir işlem yapmayacaktır.
            echo $this->pub_alt_deg." ".$this->pro_alt_deg." ".$this->pri_alt_deg;
            echo '<br/>';
        }

        public function pub_alt_fonk02()
        {
            $this->pub_alt_fonk01(); 
            // Bu fonksiyon sadece üst sınıf private değişkenini yazdırmak içindir.
            $this->pub_fonk(); 
        }   
   
        protected function pro_alt_fonk()
        {
            $this->pri_top_deg = $this->pub_alt_deg . " " . $this->pro_alt_deg . " " . 
                                 $this->pri_alt_deg;
        }
   
        private function pri_alt_fonk()
        {
            echo $this->pri_top_deg . '<br/>';
        }   
   
        public function pub_alt_hepsi_fonk()
        {
            $this->pub_alt_fonk02(); 
            $this->pro_alt_fonk();
            $this->pri_alt_fonk();
        }   
    }

    $obj = new bizim_sinif_alt ("Üstpublic", "Üstprotected", "Üstprivate", "Altpublic",
                                                           "Altprotected", "Altprivate");

    // Nesne ve -> işlemcisi yoluyla public değişkenlere erişim 
    echo $obj->pub_deg . " " . $obj->pub_alt_deg . '<br/>';

    // Nesne ve -> işlemcisi yoluyla aşağıdaki protected ve private özelliklere direk
    // erişim sağlanamaz. 
    echo $obj->pro_deg . " " . $obj->pro_alt_deg . '<br/>'; // Bu satır hata verecektir. 
    echo $obj->pri_deg . " " . $obj->pri_alt_deg . '<br/>'; // Bu satır hata verecektir.

    // Alt sınıf fonksiyonuyla üst sınıf private değişkeni hariç tüm alt ve üst sınıf
    // değişkenlerine erişim sağlanır. 
    $obj->pub_alt_fonk01();

    // Alt sınıf fonksiyonuyla tüm alt ve üst sınıf değişkenlerine erişim sağlanır
    // (Üst sınıf fonksiyonu çağrılır). 
    $obj->pub_alt_fonk02();

    // Nesne ve -> işlemcisi yoluyla aşağıdaki protected ve private yöntemlere direk
    // erişim sağlanamaz. 
    $obj->pro_alt_fonk(); // Bu satır hata verecektir.
    $obj->pri_alt_fonk(); // Bu satır hata verecektir.

    $obj->pub_alt_hepsi_fonk(); // Alt sınıftaki tüm fonksiyonlar çağrılır.
?>

</body>
</html>

Eğer yukarıdaki dosyadaki hata verecek satırları siler ve dosyayı çalıştırsanız, web taracıyınızda aşağıdaki ifadeler karşınıza çıkar:

Üstpublic Altpublic
Üstpublic Üstprotected Altpublic Altprotected Altprivate
Üstpublic Üstprotected Altpublic Altprotected Altprivate
Üstprivate
Üstpublic Üstprotected Altpublic Altprotected Altprivate
Üstprivate
Altpublic Altprotected Altprivate

Etki alanı çözünürlük işlemcisi (::)

:: işlemcisi kullanılarak bir sınıfın static, sabit ve geçersiz hale getirilmiş özellik ve yöntemlerine erişim sağlanır. Bu sınıf elemanlarına sınıf dışından erişim için:

  • :: işlemcisinin önünde sınıf adı kullanılır.
  • PHP 5.3.0'den itibaren :: işlemcisinin önünde sınıf adının atandığı bir değişken kullanılır.

<html>
<body>

<?php
    class bizim_sinif
    {
        const sabit_ust = "Sabit değer üst"; // Sabit bildirimi	
    }

    class bizim_sinif_alt extends bizim_sinif
    {
        public static $static_deg = 'static değişken';

        public static function deger_yaz() {
            echo parent::sabit_ust . '<br/>'; 
            echo self::$static_deg . '<br/>';
        }
    }

    // sınıf adı ve :: işlemcisi yoluyla sabit değere erişim
    echo bizim_sinif::sabit_ust . '<br/>'; 
   
    // Sınıf adının bir değişkene atanmasıyla (PHP 5.3.0'dan itibaren)
    // sabit değere erişim
    $sinifadi = "bizim_sinif";
    echo $sinifadi::sabit_ust . '<br/>'; 

    echo "Fonksiyonlar yoluyla yazdırma:" . '<br/>'; 
   
    bizim_sinif_alt::deger_yaz(); // sınıf adı ve :: işlemcisi yoluyla fonksiyon çağırma
   
    // Sınıf adının bir değişkene atanması yoluyla (PHP 5.3.0'dan itibaren)
    // fonksiyon çağrısı
    $sinifadi_alt = "bizim_sinif_alt";
    echo $sinifadi_alt::deger_yaz();
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

Sabit değer üst
Sabit değer üst
Fonksiyonlar yoluyla yazdırma:
Sabit değer üst
static değişken
Sabit değer üst
static değişken

Yukarıdaki PHP dosyasında, sınıf adı ve sınıf adının atandığı bir değişken, önce direk olarak sabit değer ve static değişkenlerle, daha sonra static fonksiyonla kullanılarak, sabit değer ve static değişken değerleri ekrana yazılır.

static anahtar kelimesi

Sınıf özellik ve yöntemlerinin static olarak tanımlanması, bu değerlere sınıf için bir nesne oluşturmadan erişimi sağlar. static olarak tanımlanan bir özelliğe bir sınıf için tanımlanan nesne üzerinden erişim sağlayamazsınız.

  • static yöntemler, bir nesne oluşturulmadan erişilebildiğinden, $this değişkeni static olarak bildirilen bir yöntem içinde kullanılmaz.
  • static özelliklere sınıf için tanımlanan nesne üzerinden -> işlemcisi ile erişilemez.
  • static olmayan yöntemler static bir yöntem gibi çağrılırsa, E_STRICT seviyesinde bir uyarı üretilir.

<html>
<body>

<?php
    class bizim_sinif
    {
        public static $static_deg_ust = 'static değişken üst';	

        public function static_deger_yaz_ust() {        
            echo self::$static_deg_ust . '<br/>';
        }	  
    }

    class bizim_sinif_alt extends bizim_sinif
    {
        public static $static_deg_alt = 'static değişken alt';

        public function static_deger_yaz_alt() {
            echo parent::$static_deg_ust . '<br/>'; 
            echo self::$static_deg_alt . '<br/>';
        }

        public static function static_deger_al() {
            return self::$static_deg_alt; 
        }
    }

    // Alt sınıf adı ve :: işlemcisi yoluyla üst ve alt sınıf static değişkenlere erişim   
    echo bizim_sinif_alt::$static_deg_ust . " " . bizim_sinif_alt::$static_deg_alt;
    echo '<br/>';
   
    // Alt sınıf adının bir değişkene atanması yoluyla (PHP 5.3.0'dan itibaren)
    //static değişkene erişim
    $sinifadi = "bizim_sinif_alt";
    echo $sinifadi::$static_deg_ust . " " . $sinifadi::$static_deg_alt . '<br/>'; 

    // Alt sınıf adı ve :: işlemcisi yoluyla alt sınıf static yönteme erişim   
    echo bizim_sinif_alt::static_deger_al() . '<br/>';
   
    // Alt sınıf adının bir değişkene atanması yoluyla (PHP 5.3.0'dan itibaren)
    // static yönteme erişim
    echo $sinifadi::static_deger_al() . '<br/>';
   
    $obj_alt = new bizim_sinif_alt();

    // Alt sınıf nesne ve :: işlemcisi yoluyla üst ve alt sınıf static değişkenlere 
    // erişim   
    echo $obj_alt::$static_deg_ust . " " . $obj_alt::$static_deg_alt . '<br/>';
   
    // Bu satır hata verecektir (->işlemcisi static değişkenlerle kullanılamayacağından).   
    echo $obj_alt->$static_deg_ust . " " . $obj_alt->$static_deg_alt . '<br/>';
   
    // Alt sınıf nesne ve -> işlemcisi yoluyla üst ve alt sınıf public yöntemlere erişim   
    $obj_alt->static_deger_yaz_ust();
    $obj_alt->static_deger_yaz_alt();
   
    // Üst sınıf adı ve :: işlemcisi yoluyla üst sınıf static değişkenine erişim   
    echo bizim_sinif::$static_deg_ust . '<br/>';

    $obj_ust = new bizim_sinif();
    // Üst sınıf nesne ve -> işlemcisi yoluyla üst sınıf public yönteme erişim
    $obj_ust->static_deger_yaz_ust();
?>

</body>
</html>

Eğer yukarıdaki dosyadaki hata verecek satırı siler ve dosyayı çalıştırsanız, web taracıyınızda aşağıdaki ifadeler karşınıza çıkar:

static değişken üst static değişken alt
static değişken üst static değişken alt
static değişken alt
static değişken alt
static değişken üst static değişken alt
static değişken üst
static değişken üst
static değişken alt
static değişken üst
static değişken üst

Sınıf soyutlama

PHP 5 ile birlikte gelen soyut sınıf ve yöntem kullanıldığında, soyut olarak tanımlanmış bir sınıftan bir nesne oluşturulamaz. Ayrıca, en az bir adet soyut yöntem içeren sınıfın da soyut olarak tanımlanması gerekir.

Soyut olarak tanımlanan yöntemler sadece yöntemin yapısından oluşur. İçinde uygulama satırları yer almaz.

Soyut bir sınıftan alt sınıf tanımlanırken, üst sınıfta soyut olarak tanımlanmış yöntemlerin alt sınıfta da tanımlanması gerekir. Ayrıca, bu yöntemlerin aynı (ya da daha az sınırlı) görünürlükle tanımlanması gerekir. Örneğin, soyut yöntem protected olarak tanımlanmışsa, alt sınıfta private değil, protected ya da public olarak tanımlanmalıdır.

Bir sınıftan alt sınıflar tanımlarken tüm alt sınıflarda farklı komut satırları içeren aynı ada sahip yöntemlerin bulunmasını istediğimizde, bu yöntemin sadece genel yapısını soyut olarak üst sınıf içinde tanımlamalıyız. Başka bir ifade ile, üst sınıf içinde bir yöntemi soyut olarak tanımlamak, bu sınıftan üretilecek tüm sınıflar içinde bu yöntemin aynı yapı ve isimle ancak farklı işlem satırları ile tanımlanmasını zorunlu kılar.


<html>
<body>

<?php 
    abstract class sekil
    {
        // Bu sınıftan türetilecek sınıfın içinde bu yöntemlerin tanımlanmasını zorunlu
        // kılar.    
        abstract protected function alan_hesapla();
        abstract protected function hacim_hesapla();
	 
        public function alan_al() {        
            echo $this->alan_hesapla() . '<br/>';
        }	  
    }

    class kare extends sekil
    {
        public $kenar = 5;

        public function alan_hesapla()
        {
            return $this->kenar * $this->kenar;
        }
	 
        public function hacim_hesapla()
        {
            return $this->kenar * $this->kenar * $this->kenar;
        }
    }

    class dikdortgen extends sekil
    {
        public $kenar_kisa = 5;
        public $kenar_uzun = 10;
        public $kenar_dik = 10;
	 
        public function alan_hesapla()
        {
            return $this->kenar_kisa * $this->kenar_uzun;
        }
	 
        public function hacim_hesapla()
        {
            return $this->kenar_kisa * $this->kenar_uzun * $this->kenar_dik;
        }
    }

    $obj_kare = new kare();
   
    // Üst sınıf içinde soyut olarak tanımlanmış yöntemlerine nesne ve -> işlemcisi 
    // yoluyla  direk erişim   
    echo $obj_kare->alan_hesapla() . ' ';
    echo $obj_kare->hacim_hesapla() . '<br/>';
    // Üst sınıf içinde soyut olarak tanımlanmış yöntemlerine üst sınıf yöntemiyle
    // dolaylı erişim
    $obj_kare->alan_al();

    $obj_dikdortgen = new dikdortgen();
   
    // Üst sınıf içinde soyut olarak tanımlanmış yöntemlerine nesne ve -> işlemcisi
    // yoluyla direk erişim
    echo $obj_dikdortgen->alan_hesapla() . ' ';
    echo $obj_dikdortgen->hacim_hesapla() . '<br/>';   
    // Üst sınıf içinde soyut olarak tanımlanmış yöntemlerine üst sınıf yöntemiyle
    // dolaylı erişim
    $obj_dikdortgen->alan_al();   
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

25 125
25
50 500
50

Nesne arayüzleri

Nesne arayüzleri bir sınıfta bulunması gereken yöntemleri belirlemek için kullanılır. Bu yöntemler içinde hangi kodların kullanılacağını belirlemez.

Nesne arayüzleri interface anahtar kelimesi ile sınıflara benzer bir şekilde tanımlanır. İçinde yer alan yöntemlerde herhangi bir kod yer almaz.

Nesne arayüzleri içindeki tüm yöntemler public olarak tanımlanmalıdır.

Bir arayüzden sınıf tanımı yapmak için implements işlemcisi kullanılır. Arayüzde bulunan tüm yöntemler tanımlanan sınıf içinde kod satırları ile birlikte tanımlanmalıdır. Aksi takdirde, hata ile sonuçlanır. Arayüzler virgül ile ayrılarak, bir sınıf birden fazla arayüz ile birlikte tanımlanabilir.

  • Bir sınıf aynı yöntem isimlerini içeren iki arayüz ile birlikte tanımlanamaz.
  • Arayüzler tıpkı sınıflar gibi extends işlemcisi ile genişletilebilir.
  • Sınıflarda yöntemler, arayüzlerde yapı ile aynı şekilde tanımlanmalıdır. Aksi takdirde, hata ile sonuçlanır.
  • Arayüzler içinde sabit tanımlanabilir. Ancak, tanımlanan sabitler arayüze bağlı olarak tanımlanan sınıf ve arayüzler tarafından geçersiz hale getirilecek şekilde yeniden tanımnlanamazlar.

Nesne arayüzleri ile soyut sınıf karşılaştırması:

  • Nesne arayüzleri kod içeren yöntem barındıramaz, soyut sınıflar ise barındırabilirler.
  • Nesne arayüzleri içindeki yöntem ve özellikler public olarak tanımlanmak zorundadır, soyut sınıflar için bu zorunluluk yoktur.

<html>
<body>

<?php
    interface inter_temel
    {
        // Türetilecek sınıf içinde bu yöntemlerin tanımlanmasını zorunlu kılar.    
        public function deger_ver($deger);
        public function deger_al();
    }

    interface inter_alt extends inter_temel
    {
        // Türetilecek sınıf içinde bu yöntem ile üst arayüz yöntemlerinin tanımlanmasını
        // zorunlu kılar.
        public function deger_karesi();
    }

    class sinif_temel implements inter_temel
    {
        public $deg_sinif = 5;

        public function deger_ver($deger)
        {
            $this->deg_sinif = $deger;
        }
	 
        public function deger_al()
        {
            return $this->deg_sinif;
        }
    }

    class sinif_alt implements inter_alt
    {
        public $deg_sinif_alt = 8;

        public function deger_ver($deger)
        {
            $this->deg_sinif_alt = $deger;
        }
	 
        public function deger_al()
        {
            return $this->deg_sinif_alt;
        }
	   
        public function deger_karesi()
        {
            return $this->deg_sinif_alt * $this->deg_sinif_alt;
        }
    }

    $obj_temel = new sinif_temel();
   
    echo $obj_temel->deger_ver(27);
    echo $obj_temel->deger_al() . '<br/>';

    $obj_alt = new sinif_alt();
   
    echo $obj_alt->deger_ver(38);
    echo $obj_alt->deger_al() . ' ';
    echo $obj_alt->deger_karesi() . '<br/>';   
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

27
38 1444

Özellikler (Traits)

PHP 5.4.0 ile birlikte, Traits adı verilen ve kodların yeniden kullanımını sağlayan bir sistem uygulamaya konuldu.

use anahtar kelimesi ile traits yöntemlerini bir sınıfa dahil edebilir ve traits içinde tanımlanan yöntemleri farklı sınıflar içinde kullanabilirsiniz.

Traits yapısı tıpkı sınıf yapısı gibi tanımlanır, ancak Traits yapısından kendine ait bir nesne tanımlanamaz.

Traits yapısı, extends deyimi ile kalıtım yoluyla genişletme yapmadan, içindeki yöntemlerin diğer sınıflar içinde kullanılmasını sağlar.


<html>
<body>

<?php
    class sinif_ust
    {
        public $deg = 'Üst sınıf karakter dizisi';
    }

    trait trait_temel
    {
        public function deger_yaz($deger)
        {
            echo '$deger Trait yöntemi ile ekrana yazma';  
        }	   
    }

    class sinif_alt_bir extends sinif_ust
    {
        // Trait içinde yer alan yöntemlerin bu sınıf içinde kullanılmasını sağlar.    
        use trait_temel;       
    }

    class sinif_alt_iki extends sinif_ust
    {
        // Trait içinde yer alan yöntemlerin bu sınıf içinde kullanılmasını sağlar.    
        use trait_temel;       
    }

    $obj_sinif_alt_bir = new sinif_alt_bir();
    $obj_sinif_alt_iki = new sinif_alt_iki();
   
    $obj_sinif_alt_bir->deger_yaz('İlk alt sınıftan');
    echo '<br/>';
    $obj_sinif_alt_iki->deger_yaz('İkinci alt sınıftan');   
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

İlk alt sınıftan Trait yöntemi ile ekrana yazma
İkinci alt sınıftan Trait yöntemi ile ekrana yazma

Bir sınıftan türetilen bir alt sınıf içinde Trait kullanıldığında, eğer üst ve alt sınıf ile Trait içinde aynı isime sahip yöntemler yer alıyorsa, alt sınıf Trait içindeki fonksiyonu, Trait içindeki fonksiyonda üst sınıf içindeki fonksiyonu geçersiz hale getirir.


<html>
<body>

<?php
    class sinif_ust
    {
        public function yazi_yaz()
        {
            echo 'Üst sınıf içinde yazı yazma';  
        }
		
        public function sayi_yaz()
        {
            echo 'Üst sınıf içinde sayi: 327';  
        }		
    }

    trait trait_temel
    {
        public function yazi_yaz()
        {
            echo 'Trait ile yazı yazma';
        }

        public function sayi_yaz()
        {
            echo 'Trait içinde sayi: 327';  
        }		
    }

    class sinif_alt extends sinif_ust
    {
        // Trait içinde yer alan yöntemlerin bu sınıf içinde kullanılmasını sağlar.    
        use trait_temel;
		
        public function yazi_yaz()
        {
            echo 'Alt sınıf içinde yazı yazma';
        }
    }

    $obj_sinif_alt = new sinif_alt();
   
    $obj_sinif_alt->yazi_yaz(); // Alt sınıf içindeki yöntem çağrılır.
    echo '<br/>';
    $obj_sinif_alt->sayi_yaz(); // Trait içindeki yöntem çağrılır.   
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

Alt sınıf içinde yazı yazma
Trait içinde sayi: 327

use deyiminde aralarında virgül kullanılarak, bir sınıf içinde birden fazla Trait tanımlanabilir.


<html>
<body>

<?php
    trait trait_bir
    {
        public function yazi_yaz_bir()
        {
            echo 'İlk Trait fonksiyonu';
        }
    }

    trait trait_iki
    {
        public function yazi_yaz_iki()
        {
            echo 'İkinci Trait fonksiyonu';
        }
    }

    class sinif_bizim
    {
        // Trait içinde yer alan yöntemlerin bu sınıf içinde kullanılmasını sağlar.    
        use trait_bir, trait_iki;
    }

    $obj_sinif = new sinif_bizim();
   
    $obj_sinif->yazi_yaz_bir();
    echo '<br/>';
    $obj_sinif->yazi_yaz_iki();   
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

İlk Trait fonksiyonu
İkinci Trait fonksiyonu

Çoklu görev (Overloading)

Çoklu görev, özellik ve yöntemlerin dinamik olarak oluşturulması demektir. Bu dinamik elemanlar, çeşitli hareket türleri için sınıf içinde oluşturulabilen sihirli yöntemler tarafından işlem yapılırlar.

Çoklu görev yöntemleri, henüz bildirilmemiş veya geçerli etki alanında görünür olmadığından erişilemeyen özellik ve yöntemlerle işlem yapıldığında çağrılırlar.

  • Tüm çoklu görev yöntemleri public olarak tanımlanmalıdır.
  • Sihirli yöntemlerin argümanları referans olarak aktarılamaz.
  • Nesneye yönelik programlama dillerinin çoğunda çoklu görev ile, farklı miktarda ve türde argümanlar kullanabilen, aynı isime sahip birden fazla yöntem tanımlama olanağı sağlanmaktadır. PHP'de ise çoklu görev ile sınıf içinde mevcut olmayan özellik ve yöntemler tanımlanabilmekte, erişilemeyen özellik ve yöntemlere erişim sağlanmaktadır.

Özelliklerde çoklu görev

Özelliklerde çoklu görev işlemi uygulamak için aşağıdaki sihirli fonksiyonlar kullanılır:

  • void __set (string $isim, mixed $deger) : Erişilemeyen özelliklere veri yazılırken çalıştırılır.
  • mixed __get (string $isim) : Erişilemeyen özelliklerden veri okurken kullanılır.
  • bool __isset (string $isim) : Erişilemeyen özellikler için isset() veya empty() fonksiyonu çağrıldığında tetiklenir.
  • void __unset (string $isim) : Erişilemeyen özellikler için unset() fonksiyonu çağrıldığında kullanılır.
  • Yukarıdaki fonksiyonlardaki $isim argümanı işlem yapılan özelliğin adını gösterir.
  • __set fonksiyonundaki $deger argümanı $isim ile gösterilen özelliğin değerini tanımlar.
  • Özellik çoklu görev tanımlaması sadece nesne üzerinde çalışmaktadır. Sihirli fonksiyonlar static kapsamda tetiklenmeyeceğinden static olarak bildirilmemelidir.
  • __set() fonksiyonunun geri dönderdiği değer dikkate alınmaz. Benzer şekilde, __get() fonksiyonu zincirleme atamalarda çağrılmaz.

<html>
<body>

<?php
    class sinif_bizim
    {
        // Dinamik olarak oluşturulan veriler için ayrılan yer
        private $data = array();

        // Sınıf içinde bildirilen özellikler için aşırı yükleme kullanılmaz.
        public $deg_public = 25;

        // Bu özelliğe sınıf dışından nesne ile erişilmek istendiğinde aşırı yükleme
        // kullanılır.
        private $deg_priv = 12;

        public function __set($name, $value) {
            echo "__set() fonksiyonu çalıştı: $name değişkenine '$value' değeri
                  veriliyor.";
            echo "<br/>";
            $this->data[$name] = $value;
        }

        public function __get($name) {
            echo "__get() fonksiyonu çalıştı: $name değişken değeri alınıyor.<br/>";
            if (array_key_exists($name, $this->data)) {
                return $this->data[$name];
            }
            return null;
        }

        public function __isset($name) {
            echo "__isset() fonksiyonu çalıştı: $name değişkeninin varlığı kontrol
                  edilecek!";
            echo "<br/>";
            echo 'Dinamik değişken ';
            if (isset($this->data[$name])) echo 'tanımlanmıştır!';
            else echo 'tanımlanmamıştır!';
            echo "<br/>";
        }

        public function __unset($name) {
            echo "__unset() fonksiyonu çalıştı: $name değişkeni siliniyor.<br/>";
            unset($this->data[$name]);
        }

        public function getPrivate() {
            return $this->deg_priv;
        }
    }

    $obj = new sinif_bizim();

    // Mevcut olmayan bir özelliğe değer atandığından __set() fonksiyonu tetiklenir ve
    // özellik dinamik olarak oluşturulur.
    $obj->deg_dinamik = 1;

    // Dinamik olarak oluşturulmuş bir özelliğe erişim yapıldığından __get() fonksiyonu
    // tetiklenir ve özellik değeri okunur.
    echo $obj->deg_dinamik . '<br/>';

    // Dinamik olarak oluşturulmuş bir özelliğin kontrolu yapıldığından
    // __isset() fonksiyonu tetiklenir.
    isset($obj->deg_dinamik);
    // Dinamik olarak oluşturulmuş bir özellik silineceğinden
    // __unset() fonksiyonu tetiklenir.
    unset($obj->deg_dinamik);
    // Dinamik olarak oluşturulmuş bir özelliğin kontrolu yapıldığından
    // __isset() fonksiyonu tetiklenir.
    isset($obj->deg_dinamik);
	
    // public bir değişkene nesne yoluyla erişim sağlandığından herhangi
    // bir sihirli fonksiyon çağrılmaz.
    echo $obj->deg_public . '<br/>';

    // Private özelliklere sınıf içindeki yöntemlerle erişilebildiğinden
    // __get() fonksiyonu tetiklenmez.
    echo $obj->getPrivate() . '<br/>';
    // Private özelliklere sınıf içindeki yöntemlerle erişilebildiğinden
    // __get() fonksiyonu tetiklenir.
    echo $obj->deg_priv . '<br/>';
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

__set() fonksiyonu çalıştı: deg_dinamik değişkenine '1' değeri veriliyor.
__get() fonksiyonu çalıştı: deg_dinamik değişken değeri alınıyor.
1
__isset() fonksiyonu çalıştı: deg_dinamik değişkeninin varlığı kontrol edilecek!
Dinamik değişken tanımlanmıştır!
__unset() fonksiyonu çalıştı: deg_dinamik değişkeni siliniyor.
__isset() fonksiyonu çalıştı: deg_dinamik değişkeninin varlığı kontrol edilecek!
Dinamik değişken tanımlanmamıştır!
25
12
__get() fonksiyonu çalıştı: deg_priv değişken değeri alınıyor.

Yöntemlerde çoklu görev

Yöntemlerde çoklu görev işlemi uygulamak için aşağıdaki sihirli fonksiyonlar kullanılır:

  • mixed __call (string $isim, array $argümanlar) : Bir nesne kapsamındaki erişilemeyen yöntemleri çalıştırmak için tetiklenir.
  • mixed __callStatic (string $isim, array $argümanlar) : Bir sınıf kapsamındaki erişilemeyen yöntemleri çalıştırmak için tetiklenir.
  • Yukarıdaki fonksiyonlardaki $isim argümanı çağrılan yöntemin adını gösterir.
  • $argümanlar argümanı ise $isim ile gösterilen yöntemlere aktarılan parametreleri içeren numaralandırılmış bir diziyi gösterir.

<html>
<body>

<?php
    class sinif_bizim
    {
        public function __call($name, $arguments) {
            // $name değişken değeri büyük-küçük harf duyarlıdır.
            echo "$name nesne yöntemi çalışıyor: " . implode(', ', $arguments)."<br/>";
        }
		
        // PHP 5.3.0'den itibaren
        public static function __callStatic($name, $arguments) {
            // $name değişken değeri büyük-küçük harf duyarlıdır.
            echo "$name static yöntemi çalışıyor: " . implode(', ', $arguments)."<br/>";
        }
    }

    $obj = new sinif_bizim();
	
    // Sınıf içinde olmayan bir fonksiyon çağrıldığından __call() fonksiyonu tetiklenir.
    $obj->fonk_dynamik('Nesne ile dinamik yöntem çağırma');
	
    // Sınıf içinde olmayan bir fonksiyon çağrıldığından __callStatic() fonksiyonu 
    // tetiklenir (PHP 5.3.0'den itibaren).
    sinif_bizim::fonk_dynamik('Sınıf adı ile dinamik yöntem çağırma');
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

fonk_dynamik nesne yöntemi çalışıyor: Nesne ile dinamik yöntem çağırma
fonk_dynamik static yöntemi çalışıyor: Sınıf adı ile dinamik yöntem çağırma

Nesne tekrarlama

PHP 5 ile birlikte nesneler için sağlanan bir olanakla, foreach benzeri yapılar kullanılarak, bir öğe listesi üzerinde tekrarlama işlemi yapılabilir. Öntanımlı olarak, tüm görünür özellikler tekrarlama için kullanılabilir.


<html>
<body>

<?php
    class sinif_bizim
    {
        public $deg_public01 = 5;
        public $deg_public02 = 17;
        public $deg_public03 = 24;
		
        protected $deg_prot = 'Protected özellik';
        private $deg_priv = 'Private özellik';

        public function fonk_tekrarlama() {
            echo "Sınıf içindeki tekrarlama fonksiyonu<br/>";
            foreach ($this as $key => $value) {
                echo "$key => $value<br/>";
            }
        }
    }

    $obj = new sinif_bizim();

    // Nesne yoluyla dışarıdan erişilebilen sınıf özelliklerini (public) ekrana yazma
    foreach ($obj as $key => $value) {
        echo "$key => $value<br/>";
    }
    echo "<br/>";    
    // Nesne üzerinden sınıf yöntemi yoluyla tüm sınıf özelliklerini ekrana yazma
    $obj->fonk_tekrarlama();
?>

</body>
</html>


Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

deg_public01 => 5
deg_public02 => 17
deg_public03 => 24

Sınıf içindeki tekrarlama fonksiyonu
deg_public01 => 5
deg_public02 => 17
deg_public03 => 24
deg_prot => Protected özellik
deg_priv => Private özellik

Iterator dahili arayüzünü kullanma

PHP'nin dahili arayüzlerinden biri olan Iterator ile hangi elemanların nasıl tekrarlanacağını nesnenin belirlemesi sağlanır.


<html>
<body>

<?php
    class sinif_bizim implements Iterator
    {
        private $var = array();

        public function __construct($array)
        {
            if (is_array($array)) {
                $this->var = $array;
            }
        }

        public function rewind()
        {
            echo "Başa alıyor<br/>";
            reset($this->var);
        }
  
        public function current()
        {
            $var = current($this->var);
            echo "Mevcut: $var<br/>";
            return $var;
        }
  
        public function key() 
        {
            $var = key($this->var);
            echo "Anahtar: $var<br/>";
            return $var;
        }
  
        public function next() 
        {
            $var = next($this->var);
            echo "Sonraki: $var<br/>";
            return $var;
        }
  
        public function valid()
        {
            $key = key($this->var);
            $var = ($key !== NULL && $key !== FALSE);
            echo "Geçerli: $var<br/>";
            return $var;
        }
    }

    $values = array(1, 2, 3);
    $obj = new sinif_bizim($values);

    foreach ($obj as $key => $value) {
        echo "$key: $value<br/>";
    }
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

Başa alıyor
Geçerli: 1
Mevcut: 1
Anahtar: 0
0: 1
Sonraki: 2
Geçerli: 1
Mevcut: 2
Anahtar: 1
1: 2
Sonraki: 3
Geçerli: 1
Mevcut: 3
Anahtar: 2
2: 3
Sonraki:
Geçerli: 

Yukarıdaki PHP dosyasında, nesne yoluyla sınıfta yer alan private bir diziye ilk değer verilerek ekran yazılmaktadır. Her bir ekrana yazma işleminde sınıf içinde tanımlanmış olan fonksiyonlar otomatik olarak çağrılmakta ve bu fonksiyonlarda kullanılan dizi fonksiyonları ile dizi değerlerine işlem yapılmaktadır.

IteratorAggregate dahili arayüzünü kullanma

PHP 5 ile gelen IteratorAggregate arayüzünü kullanarak herhangi bir tekrarlama fonksiyonu tanımlamadan bir sınıf oluşturabilirsiniz.


<html>
<body>

<?php
    class sinif_bizim implements IteratorAggregate
    {
        private $var = array();

        public function __construct($array)
        {
            if (is_array($array)) {
                $this->var = $array;
            }
        }
		
        // IteratorAggregate arayüzü için gerekli tanım
        public function getIterator()
        {
            return new ArrayIterator($this->var);
        }
    }
	
    $values = array(1, 2, 3);
    $obj = new sinif_bizim($values);
	
    foreach ($obj as $key => $value) {
        echo "$key: $value<br/>";
    }
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

0: 1
1: 2
2: 3

Hazır yöntemler (Patterns)

Hazır yöntemler, genel programlama sorunlarına esnek bir çözüm getiren ve en iyi uygulamaları ve doğru tasarımları açıklayan bir yoldur.

Üreteç yöntemi (Factory)

Üreteç yöntemi, nesnelerin çalışma anında oluşturulmasını sağlar. Nesnenin oluşturulmasından sorumlu olduğundan bu ismi alır. Üreteç yöntemi parametre olarak sınıf ismini alarak nesneyi oluşturur.


// dosya01.php ve deneme.php aynı dizinde olmalıdır!

// dosya01.php
<?php
    class dosya01
    {
        public $deg_pub = 27; 
	
        function yaz_deger() 
        {
            echo $this->deg_pub;
        }
    }   
?>

// deneme.php
<html>
<body>

<?php
    class sinif_bizim
    {
        // Parametreli olarak tanımlanmış factory yöntemi
        public static function factory($type)
        {
            if (include_once $type . '.php') {
                $classname = $type;
                return new $classname;
            } 
            else {
                throw new Exception('Dosya bulunamadı!');
            }
        }
    }

    $obj = sinif_bizim::factory('dosya01');

    $obj->yaz_deger();
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar:

27

Tek örnek (Singleton) yöntemi

Tek örnek yöntemi, bir sınıfın sadece tek bir kopyasının bulunması gerektiği durumlarda kullanılır. Bu durumda, aynı sınıf için her defasında new deyimi ile yeni bir kopya oluşturulması gerekmez.


<html>
<body>

<?php
    class sinif_bizim
    {
        private static $instance;
        private $count = 0;
		
        private function __construct()
        {
        }		
		
        public static function singleton()
        {
            if (!isset(self::$instance)) {
                echo 'Yeni bir kopya oluşturuluyor: ';
                $className = __CLASS__;
                self::$instance = new $className;
            }
            return self::$instance;
        }
		
        public function increment()
        {
            return $this->count++;
        }		
		
        public function __clone()
        {
            trigger_error ('Nesne kopyalamaya izin verilmez.', E_USER_ERROR);
        }		
    }

    // Sınıftan yeni bir kopya oluşturma
    // __construct() fonksiyonu private olduğundan new kullanılmamaktadır.
    $obj = sinif_bizim::singleton();
    echo $obj->increment(); // $count özellik değeri: 0
    echo $obj->increment(); // $count özellik değeri: 1

    // Oluşturulmuş kopyayı yeniden kullanma (Var olan kopyayı geri döndürme)	
    $obj2 = sinif_bizim::singleton();
    echo $obj->increment(); // $count özellik değeri: 2
    echo $obj->increment(); // $count özellik değeri: 3

    // Aşağıdaki satırlar hata verir	
    $obj3 = new sinif_bizim; // __construct() fonksiyonu private olduğundan hata verir.
    $obj4 = clone $obj;
?>

</body>
</html>

Hatalı satırları silerek yukarıdaki dosyayı çalıştırdığınızda, web taracıyınızda aşağıdaki ifadeler karşınıza çıkar:

Yeni bir kopya oluşturuluyor: 0123

Sihirli yöntemler

PHP'de __ ile başlayan tüm fonksiyon isimlerini sihirli olarak belrlemiştir. Aşağıda gösterilen yöntemler PHP sınıfları içinde sihirli yöntemler olarak kullanılırlar:

Yöntem Açıklama
__construct Bir sınıf için oluşturulan nesne kapsamında ilk değer atama işlemlerini gerçekleştirmeyi sağlar.
__destruct Bir sınıf nesnesi yok edildiğinde yapılacak işlemleri belirlemeye yarar.
__call Bir nesne kapsamındaki erişilemeyen yöntemleri çalıştırmak için tetiklenir.
__callStatic Bir sınıf kapsamındaki erişilemeyen yöntemleri çalıştırmak için tetiklenir.
__get Erişilemeyen özelliklerden veri okurken kullanılır.
__set Erişilemeyen özelliklere veri yazılırken çalıştırılır.
__isset Erişilemeyen özellikler için isset() veya empty() fonksiyonu çağrıldığında tetiklenir.
__unset Erişilemeyen özellikler için unset() fonksiyonu çağrıldığında kullanılır.
__sleep Askıdaki veriye işlem yapmak veya benzer temizlik işlemleri için kullanılır.
__wakeup Serileştirme sırasında kaybedilebilen veritabanı bağlantılarını yeniden oluşturmak ve diğer yeniden ilk değer atama işlemlerini gerçekleştirmek için kullanılır.
__toString Sınıf bir nesne yoluyla karakter dizisi olarak işlem gördüğünde, sınıfın nasıl tepki vereceğini göstermek için kullanılır.
__invoke Bir nesne bir fonksiyon olarak kullanıldığında çağrılır.
__set_state PHP 5.1.0 sürümünden beri var_export() tarafından ihraç edilen sınıflar için çağrılmaktadır.
__clone Bir nesneyi kopyalamak için clone anahtar kelimesi birlikte kullanılır.

__sleep ve __wakeup

serialize() fonksiyonu, sınıfınızda __sleep adında sihirli bir fonksiyon bulunup bulunmadığına bakar. Eğer varsa, herhangi bir serileştirme işleminden önce bu fonksiyon çalıştırılır. Bu fonksiyon nesneyi temizleyebilir ve serileştirilmesi gereken nesnenin tüm değişken isimlerinin bir dizi halinde döndürebilir. Eğer fonksiyon hiçbir şey döndürmemişse NULL serileştirilir ve bir E_NOTICE mesajı verilir.

__sleep fonksiyonu üst sınıflarda yer alan private özelliklerin isimlerini geri döndüremez. Bu işlemi yapmak E_NOTICE seviyesinde bir hata vereceğinden Serializable arayüzü kullanılabilir.

__sleep fonksiyonu temel olarak askıdaki veriye işlem yapmak veya benzer temizlik işlemleri için kullanılır. Aynı zamanda, tümüyle kaydedilmesi gerekmeyen büyük nesnelerle ile ilgili işlemlerde de kullanılabilir.

unserialize() fonksiyonu ise, __wakeup adında sihirli bir fonksiyon bulunup bulunmadığına bakar. Eğer varsa, bu fonksiyon nesnenin sahip olduğu tüm kaynakları yeniden oluşturabilir.

__wakeup fonksiyonu, serileştirme sırasında kaybedilebilen veritabanı bağlantılarını yeniden oluşturmak ve diğer yeniden ilk değer atama işlemlerini gerçekleştirmek için kullanılır.



<html>
<body>

<?php
    class sinif_bizim
    {
        protected $hat;
        private $sunucu, $kullanıcı, $parola, $db;

        public function __construct ($sunucu, $kullanıcı, $parola, $db)
        {
            $this->sunucu = $sunucu;
            $this->kullanıcı = $kullanıcı;
            $this->parola = $parola;
            $this->db = $db;
            $this->baglan();
        }

        private function baglan()
        {
            $this->hat = mysql_connect($this->sunucu, $this->kullanıcı, $this->parola);
            mysql_select_db($this->db, $this->hat);
        }

        public function __sleep()
        {
            mysql_close($this->hat);
        }

        public function __wakeup()
        {
            $this->baglan();
        }
    }
?>

</body>
</html>

__toString

__toString yöntemi, sınıf bir nesne yoluyla karakter dizisi olarak işlem gördüğünde, sınıfın nasıl tepki vereceğini gösterir. Bu fonksiyon string bir değer geri döndürmelidir, aksi takdirde E_RECOVERABLE_ERROR hatası ile sonuçlanır.


<html>
<body>

<?php
    class sinif_bizim
    {
        public $deg_pub;

        public function __construct ($deger)
        {
            $this->deg_pub = $deger;
        }

        public function __toString()
        {
            // Nesne string değer olarak işlem gördüğünde $deg_pub değişkeninin geri
            // döndürüleceğini belirler.
            return $this->deg_pub;
        }
    }

    $obj = new sinif_bizim('Sihirli fonksiyonlar');
    echo $obj;	
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar:

Sihirli fonksiyonlar

__invoke

__invoke yöntemi, bir nesne bir fonksiyon olarak kullanıldığında çağrılır (PHP 5.3.0'dan itibaren mevcuttur).


<html>
<body>

<?php
    class sinif_bizim
    {
        public function __invoke($x)
        {
            // Nesne fonksiyon olarak işlem gördüğünde $x değişkeninin ekrana
            // yazılacağını belirler.		
            echo $x . '<br/>';
        }
    }

    $obj = new sinif_bizim();
    $obj(17);
    if (is_callable($obj)) echo 'Nesne çağrılabilir!';
    else echo 'Nesne çağrılamaz!';	
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar:

17
Nesne çağrılabilir! 

__set_state

__set_state statik yöntemi, PHP 5.1.0 sürümünden beri var_export() tarafından ihraç edilen sınıflar için çağrılmaktadır.

Bu yöntemin tek parametresi array('özellik' => değer, ...) yapısında ihraç edilen özellikleri içeren bir dizidir.


<html>
<body>

<?php 
    class sinif_bizim
    {
        public $deg_pub01;
        public $deg_pub02;		
		
        public static function __set_state($dizi)
        {
            $obj_in = new sinif_bizim;
            $obj_in->deg_pub01 = $dizi['deg_pub01'];
            $obj_in->deg_pub01 = $dizi['deg_pub02'];
            return $obj_in;
        }
    }

    $obj = new sinif_bizim();
    $obj->deg_pub01 = 17;
    $obj->deg_pub02 = 'Sihirli fonksiyonlar';

    eval ('$obj02 = ' . var_export($obj, true) . ';');
                                            
    var_dump($obj02);
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar:

object(sinif_bizim)[2]
  public 'deg_pub01' => string 'Sihirli fonksiyonlar' (length=20)
  public 'deg_pub02' => null

final anahtar kelimesi

PHP 5 ile birlikte gelen final anahtar kelimesi ile bir yöntem tanımladığınızda bu yöntemin içinde bulunduğu sınıftan türetilen alt sınıflar, bu yöntemi geçersiz hale getiremezler.

final anahtar kelimesi ile tanımlanan sınıflar ise genişletilemezler, başka bir ifade ile bu sınıflardan alt sınıf türetilemez.

* Özellikler final olarak bildirilemez.


<html>
<body>

<?php
    class sinif_ust
    {
        public function deger_yaz($deger)
        {
            echo $deger . '<br/>';
        }
        
        final public function string_ekle_yaz($str01, $str02)
        {
            echo $str01 . $str02 .'<br/>';
        }		
    }

    class sinif_alt extends sinif_ust
    {
        // Bu yöntem üst sınıf içinde final olarak tanımlandığından geçersiz hale
        // getirilemez ve hata verir.
        public function string_ekle_yaz($str01, $str02)
        {
            echo $str01 . $str02 .'<br/>';
        }		
    }

    final class sinif_ust02
    {
        public function deger_yaz($deger)
        {
            echo $deger . '<br/>';
        }
        
        public function string_ekle_yaz($str01, $str02)
        {
            echo $str01 . $str02 .'<br/>';
        }		
    }

    // Bu sınıf tanımlaması üst sınıf final olarak tanımlandığından hata verir.
    class sinif_alt02 extends sinif_ust02
    {        
        public function string_ekle_yaz($str01, $str02)
        {
            echo $str01 . $str02 .'<br/>';
        }		
    }	
?>

</body>
</html>

Nesne kopyalama

Bir nesne clone anahtar sözcüğü yoluyla clone() yöntemi çağrılarak kopyalanır. Bir nesnenin __clone() yöntemi doğrudan doğruya çağrılamaz.

$nesnenin_kopyası = clone $object;

Bir nesne kopyalandığında, PHP 5 nesnenin tüm özelliklerinin yüzeysel bir kopyasını çıkartır. Diğer değişkenlere referans olan özellikler referans olarak kalacaktır.

Kopyalama tamamlanır tamamlanmaz, bir __clone() yöntemi tanımlanmışsa, değişmesi gereken özelliklere izin vermek için yeni oluşturulan nesnenin __clone() yöntemi çağrılır.


<html>
<body>

<?php
    class sinif_alt_nesne
    {
        static $instances = 0;
        public $instance;

        public function __construct() {
            $this->instance = ++self::$instances;
        }

        public function __clone() {
            $this->instance = ++self::$instances;
        }
    }

    class sinif_bizim
    {
        public $object1;
        public $object2;

        public function __clone()
        {
            // this->object'in bir kopyasını oluşturmaya zorlar, aksi takdirde aynı
            // nesneyi gösterir.
            $this->object1 = clone $this->object1;
        }
    }

    $obj =  new sinif_bizim();

    $obj->object1 = new sinif_alt_nesne();
    $obj->object2 = new sinif_alt_nesne();

    $obj2 =  clone $obj;

    echo 'Orjinal nesne:<br/>';
    print_r($obj);

    echo '<br/>Kopyalanmış nesne:<br/>';
    print_r($obj2);	
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

Orjinal nesne:
sinif_bizim Object ( [object1] => sinif_alt_nesne Object ( [instance] => 1 )
                            [object2] => sinif_alt_nesne Object ( [instance] => 2 )
                          ) 
Kopyalanmış nesne:
sinif_bizim Object ( [object1] => sinif_alt_nesne Object ( [instance] => 3 ) 
                            [object2] => sinif_alt_nesne Object ( [instance] => 2 ) 
                          ) 

Nesnelerin karşılaştırılması

Karşılaştırma işlemcisi (==) kullanıldığında, eğer iki nesne aynı niteliklere ve değerlere sahipse ve aynı sınıftan oluşturulmuşlarsa bu iki nesne birbirine eşittir.

Diğer yandan, benzerlik işlemcisi (===) kullanıldığında, iki nesne sadece aynı sınıftan oluşturulmuşlarsa birbirlerinin aynısıdırlar.


<html>
<body>

<?php
    function bool2str($bool)
    {
        if ($bool === false) {
            return 'YANLIŞ';
        } 
        else {
            return 'DOĞRU';
        }
    }

    function compareObjects(&$o1, &$o2)
    {
        echo '== kontrolü : ' . bool2str($o1 == $o2) . "<br/>";
        echo '!= kontrolü : ' . bool2str($o1 != $o2) . "<br/>";
        echo '=== kontrolü : ' . bool2str($o1 === $o2) . "<br/>";
        echo '!== kontrolü : ' . bool2str($o1 !== $o2) . "<br/>";
    }

    class sinif_bizim
    {
        public $deg_pub;

        public function deger_ver($deger) 
        {
            $this->deg_pub = $deger;
        }
    }

    class sinif_bizim02
    {
        public $deg_pub;

        public function deger_ver($deger) 
        {
            $this->deg_pub = $deger;
        }
    }

    $obj01 = new sinif_bizim();
    $obj02 = new sinif_bizim();
    $obj03 = $obj01;
    $obj04 = new sinif_bizim02();

    // Aynı sınıfa ait iki nesne karşılaştırması
    echo 'Aynı sınıfa ait iki nesne:<br/>';
    compareObjects($obj01, $obj02);

    // Aynı nesneye ait iki referans karşılaştırması
    echo 'Aynı nesneye ait iki referans:<br/>';
    compareObjects($obj01, $obj03);

    // İki farklı sınıfa ait iki nesne karşılaştırması
    echo 'İki farklı sınıfa ait iki nesne:<br/>';
    compareObjects($obj01, $obj04);	
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

Aynı sınıfa ait iki nesne:
== kontrolü : DOĞRU
!= kontrolü : YANLIŞ
=== kontrolü : YANLIŞ
!== kontrolü : DOĞRU
Aynı nesneye ait iki referans:
== kontrolü : DOĞRU
!= kontrolü : YANLIŞ
=== kontrolü : DOĞRU
!== kontrolü : YANLIŞ
İki farklı sınıfa ait iki nesne:
== kontrolü : YANLIŞ
!= kontrolü : DOĞRU
=== kontrolü : YANLIŞ
!== kontrolü : DOĞRU

Tür zorlaması (Type hinting)

PHP 5 ile birlikte gelen tür zorlama özelliği ile fonksiyonlar parametrelerini nesne veya dizi (PHP 5.1'den itibaren) olmaya zorlayabilmektedir. Nesne şeklinde zorlama için fonksiyon bildiriminde sınıf adı tanımlanmalıdır. Ancak, öntanımlı parametre değeri olarak NULL kullanılırsa, sonraki fonksiyon çağrılarında argüman olarak değerlendirilir.


<html>
<body>

<?php
    class sinif_bizim
    {
        public $deg_pub = 'Bizim sınıf değişkeni';
	
        // İlk parametre sinif_diger sınıfının bir nesnesi olmalıdır.
        public function deger_yaz(sinif_diger $obj) 
        {
            echo "$obj->deg_pub<br/>";
        }

        // İlk parametre bir dizi olmalıdır.
        public function dizi_yaz(array $input_array) 
        {
            print_r ($input_array);
        }
    }

    class sinif_diger
    {
        public $deg_pub = 'Diğer sınıf değişkeni';
    }
	
    // İlk parametre sinif_bizim sınıfının bir nesnesi olmalıdır
    // (Fonksiyonlarda tür zorlaması).
    function Fonk_Tur_Zor (sinif_bizim $obj) 
    {
        echo "lt;br/>$obj->deg_pub<br/>";
    }

    // Her bir sınıfın nesnesi
    $obj_bizim = new sinif_bizim();
    $obj_diger = new sinif_diger();

    // Fonksiyon argümanı sinif_diger sınıfından bir nesne olması gerektiğinden hata
    // verecektir.
    $obj_bizim->deger_yaz('Tür zorlama örneği');

    // Fonksiyon argümanı null bir değer olmaması gerektiğinden hata verecektir.
    $obj_bizim->deger_yaz(null);

    // Ekrana 'Diğer sınıf değişkeni' yazacaktır.
    $obj_bizim->deger_yaz($obj_diger);

    // Fonksiyon argümanı bir dizi olması gerektiğinden hata verecektir.
    $obj_bizim->dizi_yaz('Tür zorlama örneği');

    // Dizi değerlerini ekrana yazacaktır.
    $obj_bizim->dizi_yaz(array('a', 'b', 'c'));
	
    // Ekrana 'Bizim sınıf değişkeni' yazacaktır.
    Fonk_Tur_Zor($obj_bizim);	
?>

</body>
</html>

Hatalı satırları silerek yukarıdaki dosyayı çalıştırdığımızda, web taracıyımızda aşağıdaki ifadeler karşımıza çıkar:

Diğer sınıf değişkeni
Array ( [0] => a [1] => b [2] => c )
Bizim sınıf değişkeni

Son statik bağlantılar (Late static bindings)

PHP 5.3.0 ile birlikte eklenen son statik bağlantılar özelliği ile çağrılan sınıf statik kalıtım kapsamında referans gösterilebilir.

Son statik bağlantılar özelliğini kullanmak için üst sınıftan türetilen bir alt sınıf ve bu alt sınıf içinde tanımlanarak üst snıfta geçersiz hale getirilmiş statik yöntem veya yöntemlerin bulunması gerekir.

Bu özellik ile en son tanımlanan sınıf içinde yer alan statik fonksiyonun çalışması sağlanır.


<html>
<body>

<?php
    class sinif_ust01 {
        public static function sinif_adi() 
        {
            echo "Üst sınıf static fonksiyonu çalışıyor: " . __CLASS__ . "<br/>";
        }
        public static function sinif_adi_al() 
        {
            self::sinif_adi();
        }
    }

    class sinif_alt01 extends sinif_ust01 {
        public static function sinif_adi() 
        {
            echo "Alt sınıf static fonksiyonu çalışıyor: " . __CLASS__ . "<br/>";
        }
    }    
	
    class sinif_ust02 {
        public static function sinif_adi() 
        {
            echo "Üst sınıf static fonksiyonu çalışıyor: " . __CLASS__ . "<br/>";
        }
        public static function sinif_adi_al() 
        {
            // Son statik bağlantılar uygulaması
            static::sinif_adi();
        }
    }

    class sinif_alt02 extends sinif_ust02 {
        public static function sinif_adi() 
        {
            echo "Alt sınıf static fonksiyonu çalışıyor: " . __CLASS__ . "<br/>";
        }
    }

    sinif_alt01::sinif_adi_al();	
    sinif_alt02::sinif_adi_al();	
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

Üst sınıf static fonksiyonu çalışıyor: sinif_ust01
Alt sınıf static fonksiyonu çalışıyor: sinif_alt02

self:: veya __CLASS__ gibi bulunduğu sınıfa statik referans yapan öğeler, bulundukları yöntemin içinde yer aldığı sınıf kapsamında değerlendirilirler. Son statik bağlantılar, static anahtar kelimesini kullanarak, ilk çağrılan sınıfı referans olarak gösterir.

Statik olmayan koşullarda, çağrılan sınıf nesne değerinin sınıfıdır. $this-> ifadesi aynı kapsamda private yöntemleri çağıracağından, static:: ifadesini kullanmak farklı sonuçlar verebilir. Diğer bir fark ise, static:: ifadesinin sadece static özellikleri göstermesidir.


<html>
<body>

<?php
    class sinif_ust {
        private function sinif_adi() 
        {
            echo "Üst sınıf private fonksiyonu çalışıyor: " . __CLASS__ . "<br/>";
        }
        public function sinif_adi_al() 
        {
            $this->sinif_adi();
            static::sinif_adi();
        }
    }

    class sinif_alt01 extends sinif_ust {
        // sinif_adi() sinif_alt01 sınıfına kopya edildiğinden, yöntemin çalışma kapsamı
        // sinif_ust sınıfı olacaktır.
    }    

    class sinif_alt02 extends sinif_ust {
        private function sinif_adi() 
        {
            // Orjinal yöntem değiştirildiğinden, yöntemin çalışma kapsamı sinif_alt02
            // sınıfı olacaktır.
        }
    }

    $obj_alt01 = new sinif_alt01();
    $obj_alt01->sinif_adi_al();

    $obj_alt02 = new sinif_alt02();
    // sinif_alt02 sınıfı sinif_adi() fonksiyonu private olduğundan hata verir.
    $obj_alt02->sinif_adi_al();	
?>

</body>
</html>

Hatalı satırı silerek yukarıdaki dosyayı çalıştırdığınızda, web taracıyınızda aşağıdaki ifadeler karşınıza çıkar:

Üst sınıf private fonksiyonu çalışıyor: sinif_ust
Üst sınıf private fonksiyonu çalışıyor: sinif_ust
Üst sınıf private fonksiyonu çalışıyor: sinif_ust

Son statik bağlantıların çalışması tamamen çözümlendiği noktada durur. Diğer taraftan, parent:: veya self:: gibi anahtar sözcüklerle yapılan statik çağrılar çağrı bilgisini yönlendirirler.


<html>
<body>

<?php
    class sinif_ust {
        public static function sinif_adi() 
        {
            echo "Üst sınıf static fonksiyonu çalışıyor: " . __CLASS__ . "<br/>";
        }
        public static function sinif_adi_ust() 
        {
            static::sinif_adi();
        }
    }

    class sinif_alt01 extends sinif_ust {
        public static function sinif_adi() 
        {
            echo "sinif_alt01 static fonksiyonu çalışıyor: " . __CLASS__ . "<br/>";
        }
		
        public static function sinif_adi_al() 
        {
            sinif_ust::sinif_adi_ust();
            parent::sinif_adi_ust();			
            self::sinif_adi_ust();			
        }		
    }    
	
    class sinif_alt02 extends sinif_alt01 {
        public static function sinif_adi() 
        {
            echo "sinif_alt02 static fonksiyonu çalışıyor: " . __CLASS__ . "<br/>";
        }
    }

    sinif_alt02::sinif_adi_al();	
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar:

Üst sınıf static fonksiyonu çalışıyor: sinif_ust
sinif_alt02 static fonksiyonu çalışıyor: sinif_alt02
sinif_alt02 static fonksiyonu çalışıyor: sinif_alt02

Nesneler ve referanslar

PHP 5 nesneye yönelik programlamanın temel kavramlarından birisi "nesneler öntanımlı olarak referans şeklinde geçirilir" şeklinde bilinmektedir. Aslında, bu kavram tamamen doğru değildir.

Bir PHP referansı, iki farklı değişkenin aynı değeri değiştirmesini sağlayan, başka bir isim olarak tanımlanabilir. PHP 5'ten itibaren bir nesne değişkeni artık nesnenin kendisini bir değer olarak içermemektedir. Bunun yerine, nesneye erişmek isteyen kavramların asıl nesneyi bulmasını sağlayacak bir nesne tanıtıcısı içerir. Bir nesne argüman olarak gönderildiğinde, döndürüldüğünde veya başka bir değişkene atandığında, bu değişkenler başka bir isim olarak değil farklı değişkenler olarak değerlendirilirler. Bu değişkenler, aynı nesneyi gösteren tanıtıcının birer kopyasını içerirler.


<html>
<body>

<?php
    class sinif_bizim {
        public $deg_pub = 1;
    }

    $obj01 = new sinif_bizim();
    $obj02 = $obj01; // $obj01 ve $obj02 aynı tanıtıcının kopyalarıdır.

    $obj02->deg_pub = 2;
    echo $obj01->deg_pub . "<br/>";

    $obj03 = new sinif_bizim();
    $obj04 = &$obj03; // $obj03 ve $obj04 aynı tanıtıcı için birer referanstır.
	
    $obj04->deg_pub = 2;
    echo $obj03->deg_pub . "<br/>";
	
    $obj05 = new sinif_bizim();

    function deger_ver($obj) {
        // $obj05 and $obj04 aynı tanıtıcıya eşittir.
        $obj->deg_pub = 2;
    }

    deger_ver($obj05);
    echo $obj05->deg_pub . "<br/>";	
?>

</body>
</html>

Yukarıdaki dosyayı çalıştırdığımızda, web tarayıcımızda aşağıdaki ifadeler karşımıza çıkar::

2
2
2

Nesne serileştirme (Object serialization)

serialize() fonksiyonu kendisine argüman olarak verilen PHP değerini dosyaya aktarılabilecek bir karakter dizisine çevirerek (dizgeleştirerek) geri verir. unserialize() fonksiyonu ise, serialize() fonksiyonunun yaptığı işlemin tam tersini yaparak, karakter dizisini PHP değerlerine çevirir (nesneleştirir).

serialize() fonksiyonu bir nesne ile kullanıldığında, tüm değişkenleri bir nesne içine kaydeder. Bir nesne içindeki yöntemler kaydedilmez, sadece sınıf adı kaydedilir.

serialize() fonksiyonu ile işlem yapılarak bir dosyaya kaydedilen bir nesneyi farklı bir dosyada kullanmak için, o dosyanın başında işlem gören sınıf tanımlamasının yapılması gerekir.


// dosya_sinif.php, deneme01.php ve deneme02.php aynı dizinde olmalıdır!

// dosya_sinif.php
<?php  
    class sinif_bizim 
    {
        public $deg_pub = 1;
    
        public function deger_goster() {
            echo $this->deg_pub;
        }
    }
?>

// deneme01.php
<html>
<body>

<?php
    include("dosya_sinif.php");
  
    $obj = new sinif_bizim();
    $obj_seri = serialize($obj);
    // $obj_seri değişkenini deneme01.php dosyasının bulacağı bir dosyaya aktarır.
    file_put_contents('aktar.txt', $obj_seri);  
?>

</body>
</html>

// deneme02.php
<html>
<body>

<?php
    include("dosya_sinif.php");
  
    // $obj_seri değişkenine aktar.txt dosyasından aldığı verileri aktarır.
    $obj_seri = file_get_contents('aktar.txt');
	
    $obj = unserialize($obj_seri);
    $obj->deger_goster();  
?> 

</body>
</html>

Yukarıdaki deneme01.php ve deneme02.php dosyalarını sırasıyla çalıştırdığımızda, web taracıyımızda aşağıdaki ifade karşımıza çıkar:

1

Yukarıdaki deneme01.php dosyasında oluşturulan yeni bir nesne serileştirilerek 'aktar.txt' adlı dosyaya aktarılır. deneme02.php dosyasında ise 'aktar.txt' dosyasında bulunan veriler bir değişkene aktarılır. Veriler seri halden normal hale çevrilerek farklı bir değişkene aktarılır ve sınıf yöntemi yoluyla sınıf özelliği ekrana yazılır.