Sınıflar ve Nesneler
PHP Manual

Duruk İçselleştirim

PHP 5.3.0'dan itibaren, miras alınan duruk bağlamın çağrıldığı nesne bağlamında değerlendirilmesini sağlayan ve duruk içselleştirim (İng.: late static bindings) adı verilen bir özellik eklenmiştir.

"Duruk içselleştirme", static:: yöntemin çalışma anında, tanımlandığı nesnenin bağlamında değil, çağrıldığı nesnenin bağlamında değerlendirilmesi olgusunu betimler.

self:: ile ilgili sınırlamalar

self:: veya __CLASS__ gibi bulunduğu sınıfa duruk gönderim yapan öğeler, örnekten de görüleceği üzere, yöntemi miras alan sınıf bağlamında değil, yöntemin ait olduğu sınıf bağlamında değerlendirilirler:

Örnek 1 - self:: kullanımı

<?php
class {
    public static function 
kimsin() {
        echo 
__CLASS__;
    }
    public static function 
dene() {
        
self::kimsin();
    }
}

class 
extends {
    public static function 
kimsin() {
        echo 
__CLASS__;
    }
}

B::dene();
?>

Yukarıdaki örneğin çıktısı:

A

Duruk İçselleştirimin uygulanması

Duruk içselleştirimde çözümlemenin, gönderimin çalışma anında ilk çağrıldığı sınıfla sınırlandırılması, gönderim için özel bir anahtar sözcük kullanılarak sağlanır. Temel olarak, böyle bir anahtar sözcük, yukarıdaki örnekteki dene() yönteminin aşağıdaki gibi B döndürmesini sağlar. Bunun için yeni bir anahtar sözcük atamaktansa, zaten bir anahtar sözcük olan static sözcüğü kullanılmıştır.

Örnek 2 - static:: kullanımı

<?php
class {
    public static function 
kimsin() {
        echo 
__CLASS__;
    }
    public static function 
dene() {
        static::
kimsin(); // Burada duruk içselleştirim yapılıyor
    
}
}

class 
extends {
    public static function 
kimsin() {
         echo 
__CLASS__;
    }
}

B::dene();
?>

Yukarıdaki örneğin çıktısı:

B

Bilginize:

Duruk yöntemler için static::, $this gibi çalışmaz! $this-> kalıtım kurallarına bağlıdır, static:: değildir.

Örnek 3 - Duruk olmayan bağlamda static:: kullanımı

<?php
class Çocuk extends Ebeveyn {
    public function 
__construct() {
        static::
kimsin();
    }

    public function 
dene() {
        
$o = new Ebeveyn();
    }

    public static function 
kimsin() {
        echo 
__CLASS__."\n";
    }
}

class 
Ebeveyn {
    public function 
__construct() {
        static::
kimsin();
    }

    public static function 
kimsin() {
        echo 
__CLASS__."\n";
    }
}
$o = new Çocuk;
$o->dene();

?>

Yukarıdaki örneğin çıktısı:

Çocuk
Ebeveyn

Bilginize:

Duruk içselleştirimin çözümlemesi duruk çağrının tamamen çözümlendiği noktada durdurulur, daha öteye gidilmez. Diğer taraftan, parent:: veya self:: gibi anahtar sözcükler kullanılarak yapılan duruk çağrılar çağrı bilgisini ötelerler.

Örnek 4 Ötelenen ve ötelenmeyen çağrılar

<?php
class {
    public static function 
nesin() {
        static::
kimsin();
    }

    public static function 
kimsin() {
        echo 
__CLASS__."\n";
    }
}

class 
extends {
    public static function 
dene() {
        
A::nesin();
        
parent::nesin();
        
self::nesin();
    }

    public static function 
kimsin() {
        echo 
__CLASS__."\n";
    }
}
class 
extends {
    public static function 
kimsin() {
        echo 
__CLASS__."\n";
    }
}

C::dene();
?>

Yukarıdaki örneğin çıktısı:

A
C
C

Yan etkiler

PHP'de bir yöntem çağrısını tetiklemenin çok çeşitli yolları vardır; geri çağırımlar ve sihirli yöntemler gibi. Bunlar duruk içselleştirime tabi tutulduklarında, çalışma anında beklenmeyen sonuçlara sebep olurlar.

Örnek 5 - Sihirli yöntemlerin içinde duruk içselleştirim

<?php
class {

   protected static function 
kimsin() {
        echo 
__CLASS__."\n";
   }

   public function 
__get($var) {
       return static::
kimsin();
   }
}

class 
extends {

   protected static function 
kimsin() {
        echo 
__CLASS__."\n";
   }
}

$b = new B;
$b->nesin;
?>

Yukarıdaki örneğin çıktısı:

B

Sınıflar ve Nesneler
PHP Manual