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ırlamalarself::
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 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::
veyaself::
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