Statik İçselleştirim

Statik içselleştirim (İng.: late static bindings) ile miras alınan statik bağlam, tanımlandığı nesnenin bağlamında değil, çağrıldığı nesnenin bağlamında değerlendirilir.

Daha kesin olarak, statik içselleştirim son "ötelenmeyen çağrıda" bahsi geçen sınıfın saklanmasıyla çalışır. Statik yöntem çağrısı durumunda sınıfın adı açıkça (genellikle :: işlecinin sol tarafında) belirtilmiştir. Statik olmayan yöntem çağrısı durumunda söz konusu sınıf, nesnenin sınıfıdır. Bir "ötelenen çağrı", bir self::, parent::, static:: yöntemi veya sınıf hiyerarşisi üzerinden gidiliyorsa forward_static_call() çağrısıdır. get_called_class() işlevi, çağrılan sınıfın ismini bir dize olarak almakta kullanılabilir ve bağlamını static:: belirler.

"Statik 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 statik 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 A {
public static function
kimsin() {
echo
__CLASS__;
}
public static function
dene() {
self::kimsin();
}
}

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

B::dene();
?>

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

 A 

Statik İçselleştirimin uygulanması

Statik 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 A {
public static function
kimsin() {
echo
__CLASS__;
}
public static function
dene() {
static::
kimsin(); // Burada statik içselleştirim yapılıyor
}
}

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

B::dene();
?>

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

 B 

Bilginize:

Statik olmayan bağlamlarda, çağrılan sınıf, nesne örneğinin sınıfı olacaktır. $this-> aynı bağlamdaki private yöntemleri çağırmayı denerken, static:: kullanımı farklı sonuçlar verebilir. static:: ile ilgili diğer bir fark, sadece statik özellikler için kullanılabilmesidir.

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

<?php
class A {
private function
foo() {
echo
"success!\n";
}

public function
dene() {
$this->foo();
static::
foo();
}
}

class
B extends A {

}

class
C extends A {
private function
foo() {

}
}

$b = new B();
$b->test();
$c = new C();
$c->test(); //hata verir
?>

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

 success! success! success! Fatal error: Call to private method C::foo() from context 'A' in /tmp/test.php on line 9 

Bilginize:

Statik içselleştirimin çözümlemesi statik ç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 statik çağrılar çağrı bilgisini öteler.

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

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

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

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

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

C::dene();
?>

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

 A C C 
To Top