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 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 {
/* foo() B'ye kopyalanacak, dolayısıyls bağlamı hala A olacak ve
* çağrı başarılı olacaktır. */
}
class C extends A {
private function foo() {
/* özgün yöntem değişti; yenisinin bağlamı C'dir */
}
}
$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