Giới thiệu
Tính năng late static binding trong PHP dùng để tham chiếu đến class được gọi (called class) trong static inheritance. Khi gọi static method, tên class gắn với scope resolution operator (::) trong khi instance method gọi qua tên object. static:: sẽ không được resolve bằng class nơi method được định nghĩa, mà được tính toán dựa trên thông tin runtime. Static reference đến class hiện tại được resolve bằng class chứa function, không phải nơi nó được định nghĩa.
Ví dụ
Vấn đề với self::
<?php
class Test1 {
public static $name = "Raja";
public static function name() {
echo "name of class: " . __CLASS__;
}
public static function getname() {
self::name();
}
}
class Test2 extends Test1 {
public static function name() {
echo "name of class: " . __CLASS__;
}
}
Test2::getname();
?>
Kết quả
name of class: Test1
Kết quả trả về tên parent class thay vì child class như mong đợi.
Giải quyết với static:: (Late Static Binding)
<?php
class Test1 {
public static function name() {
echo "name of class: " . __CLASS__;
}
public static function getname() {
static::name(); // late static binding
}
}
class Test2 extends Test1 {
public static function name() {
echo "name of class: " . __CLASS__;
}
}
Test2::getname();
?>
Kết quả
name of class: Test2
Giờ trả về tên child class như mong đợi.
static:: trong ngữ cảnh non-static
Private method trong parent được copy sang child, nên scope vẫn là parent.
<?php
class Test1 {
private function name() {
echo "name of class: " . __CLASS__ . "\n";
}
public function getname() {
$this->name();
static::name();
}
}
class Test2 extends Test1 {
// không override name()
}
$t2 = new Test2();
$t2->getname();
?>
Kết quả
name of class: Test1 name of class: Test1
Tuy nhiên, khi parent method bị override, scope thay đổi:
class Test3 extends Test1 {
private function name() {
/* original method bị thay thế; scope của name giờ là Test3 */
}
}
$t3 = new Test3();
$t3->name();
Kết quả
PHP Fatal error: Uncaught Error: Call to private method Test3::name() from context ''