Bài 14: Sự khác nhau giữa self và $this trong PHP

PHP nâng cao 24/01/2017 11:04 3690
Thông thường khi truy xuất vào một thuộc tính, phương thức của một đối tượng, ta thường dùng $this. Nhưng khi truy xuất vào những thuộc tính static, có thể đối tượng đó chưa được khởi tạo nên ta không thể truy xuất qua $this được, bởi vậy ta cần dùng self để truy xuất.

1. Tổng quát

  • $this sẽ trỏ tới đối tượng hiện thời
  • self sẽ trỏ tới class hiện thời

Cú pháp: self::property

Ví dụ 01:

class MyClass{
    private $non_static_member = 'Non static';
    private static $static_member  = 'Static';
    
    function __construct(){
        // Non Static
        echo self::$non_static_member;
        // Static
        echo self::$static_member;
    }
}
// Khai báo đối tượng
$class = new MyClass();
// Kết quả:
// echo self::$non_static_member; Fatal error: Access to undeclared static property: MyClass::$non_static_member
// echo self::$static_member; Static.

Ví dụ 02:

class MyClass{
    private $non_static_member = 'Non static';
    private static $static_member  = 'Static';
    
    function __construct(){
        // Non Static
        echo $this->non_static_member;
        // Static
        echo self::$static_member;
    }
}
// Khai báo đối tượng
$class = new MyClass();
// Kết quả:
// echo self::$non_static_member; => Non static
// echo self::$static_member; => Static.

Kết luận:  $this cho non-static member, và self cho static member

Tuy nhiên, khi tạo lập tính đa hình (polymorphism) cho đối tượng, ta không thể dùng self để thay thế cho $this, ta có thể thấy rõ điều này trong ví dụ sau:

class Animal{
    function _sleep(){
        echo 'Animal sleeping';
    }
    function info(){
        $this->_sleep();
    }
}
class Dog extends Animal{
    function _sleep(){
        echo 'Dog sleeping';
    }
}
// Khai báo đối tượng
$animal = new Animal();
$animal->info(); // Kết quả "Animal sleeping";
// Còn nếu
$animal = new Dog();
$animal->info(); // Kết quả "Dog sleeping";
Nếu đối tượng Animal được khởi tạo, thì kết quả sẽ là "Animal sleeping", còn nếu Dog được khởi tạo thì kết quả sẽ là "Dog sleeping";

Nếu chúng ta sử dụng self:

class Animal{
    function _sleep(){
        echo 'Animal sleeping';
    }
    function info(){
        self::_sleep();
    }
}
class Dog extends Animal{
    function _sleep(){
        echo 'Dog sleeping';
    }
}
// Khai báo đối tượng
$animal = new Dog();
$animal->info(); // Kết quả "Animal sleeping";

Kết quả sẽ lại là "Animal sleeping", vì khi sử dụng self, thì nó sẽ trỏ đến chính class Animal, cho dù ta khởi tạo Animal hay Dog. Như vậy tính đa hình sẽ bị loại bỏ hoàn toàn khi sử dụng self.

2. Sử dụng self và this trong static function.

- Con trỏ $this không thể được sử dụng bên trong một phương thức static. Nhưng nó có thể được dùng để gọi một phương thức static.

Ví dụ:

class Animal{
    public static $Name;
    
    function __construct($Name){
        self::$Name = $Name;
    }
    public static function _getName(){
        echo self::$Name;
    }
    function _getInfo(){
        $this->_getName();
    }
}
// Khai báo đối tượng
$animal = new Animal('Dog');
$animal->_getInfo(); // Kết quả "Dog";

- Luôn sử dụng self để tham chiếu đến các biến hay phương thức static. Không nên sử dụng con trỏ $this để thay đổi giá trị biến static.

Ví dụ:

class Animal{
    public static $Name;
    
    public static function _setName($Name){
        self::$Name = $Name;
    }
    public function _getName(){
        echo self::$Name;
    }
}
// Khai báo đối tượng
$animal = new Animal();
$animal->_setName('Super Dog');
$animal->_getName(); // Kết quả "Super Dog";

Xem Thêm

Profile photo of adminTheHalfHeart

B.V.T

Sinh ra và lớn nên ở Bắc Giang. Hiện tại thì tôi đang là một lập trình viên tại VietISO. Tôi lập website này với mục đích là bookmark những gì tôi đã đọc qua và mong muốn chia sẻ những gì tôi biết.