Khác nhau giữa "self" và "static" trong PHP

PHP 5.3 giới thiệu tính năng có tên là late static binding trong đó sự tương tự giữa cách sử dụng của hai từ khoá selfstatic có thể khiến nhiều bạn cảm thấy bối rối. Để phân biệt được sự khác biệt này chúng ta hãy cùng nhau tham khảo một ví dụ sau:

<?php
class Monkey
{
    protected static $legs = 4;

    public static function countLegs() {
         return self::$legs;
    }
}

class Human extends Monkey
{
    protected static $legs = 2;
}

Ở trên chúng ta có hai class Monkey (động vật) và Human (con người) trong đó class Human thừa kế lại class Monkey. Trong class Monkey chúng ta có thuộc tính $legs được khai báo là thuộc tính static. Điều này là hợp lý vì chúng ta muốn số lượng chân của Monkey không thay đổi cho tất cả các object sinh ra từ class này. Trong lớp Human thuộc tính này được override lại về giá trị là 2.

Bây giờ chúng ta sẽ thử gọi phương thức countLegs() có trong lớp Human bằng việc thêm đoạn code dưới đây vào phía cuối:

echo Human::countLegs() . "\n";

Lúc này nếu chạy đoạn code trên thì giá trị trả về là 4 trong khi giá trị chúng ta cần là 2. Điều này xảy ra là bởi vì khi sử dụng self thì giá trị thuộc tính sẽ được tham chiếu về giá trị của thuộc tính trong lớp cha thay vì lớp hiện tại.

Để khắc phục tình trạng trên PHP phiên bản 5.3 cung cấp tính năng late static binding.

Late Static Binding trong PHP

Để hiểu late static binding là gì thì thì bạn thay đổi đoạn code khai báo lớp Monkeyở trên thành như sau:

<?php
class Monkey
{
    protected static $legs = 4;

    public static function countLegs() {
         return static::$legs;
    }
}

Ở đoạn code cập nhật phía trên chúng ta chỉ thay đổi khoá self bằng từ khoá static trong phương thức countLegs(), còn lại các phần khác vẫn được giữ nguyên.

Bây giờ nếu chạy đoạn code được cập nhật bạn sẽ có kết quả trả về là 4 thay vì là 2 như trước đây. Đây chính là cái gọi là late static binding trong PHP. Khi sử dụng từ khoá static thay vì selfthì giá trị của thuộc tính trong phương thức countLegs() sẽ tham chiếu tới giá trị trong lớp hiện tại đang sử dụng để gọi phương thức này (ở ví dụ trên là giá trị thuộc tính $legs trong lớp Human thay vì Monkey.

Bài Tập Nhỏ Phân Biệt selfstatic

Ở trên chúng ta đã tìm hiểu về late static binding. Để chắc chắn bạn đã hiểu về khái niệm này thì bây giờ bạn hãy tham khảo đoạn code phía dưới và đoán xem giá trị trả về là gì?

<?php
class A {
    public static function returnClassName() {
        return __CLASS__;
    }
    public static function printClassName() {
        self::returnClassName();
    }
}

class B extends A {
    public static function returnClassName() {
        return __CLASS__;
    }
}

B::printClassName();

Để lại comment phía dưới nếu bạn đã có câu trả lời : )

1 Bình Luận

Bean Wiliam Bean Wiliam

Trong class A method printClassName thiếu return nên nó return NULL.

Nội dung không được để trống

Bài Viết Liên Quan