Hướng dẫn php self vs static - php self vs static

Hướng dẫn php self vs static - php self vs static

Show

Đã đăng vào thg 4 27, 2017 6:51 SA 2 phút đọc 2 phút đọc

Như ở phần cuối của bài static và final trong PHP mình có nói là giữa static và self nó có khác nhau ở trong một số trường hợp. Và để chứng minh cho điều đó thì bài hôm nay mình sẽ giới thiệu với mọi người những sự khác nhau đó.

1, Tổng quan.

Nhìn chung thì cả

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 và
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
4 đều dùng để gọi các thành phần tĩnh trong đối tượng, nhưng nếu chỉ đơn thuần như trong nội bộ class thì cả 2
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
5 này đều cho ra kết quả tốt.

VD::

';
        echo static::$name;
    }
}

ConNguoi::getName();

Kết Quả::

ConNguoi
ConNguoi

Vậy liệu nó có cho ra các giá trị khác nhau khi chúng ta sử dụng tính kế thừa trong class? Để biết rõ hơn thì chúng ta sẽ tạ ra các ví dụ để so sánh nó.

2, So Sánh và kết luận.

Vẫn là class ConNguoi như trên nhưng chúng ta sẽ khai báo thêm một class NguoiLon kế thừa class ConNguoi và override lại thuộc tính $name như sau:

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();

Sau khi chạy dòng trên thì mình thu được kết quả như sau:

ConNguoi

Fatal error: Cannot access private property NguoiLon::$name

-Như các bạn đã thấy: Đối với self thì kết quả chạy như bình thường, còn với static thì sao nó lại báo là không thể truy cập vào thuộc tính private mà lại là NguoiLon::$name, phải chăng thằng static này đại diện cho đối tượng hiện tại nên không thể truy xuất được đến thuộc tính $name. Thôi được rồi, để chắc ăn hơn thì mình thử đổi visibility của biến $name thành protected xem sao?

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    protected static $name = 'NguoiLon';
}
// NguoiLon::getName();
$a = new NguoiLon();
$a->getName();

Và đây là kết quả mình nhận được:


ConNguoi
NguoiLon

Giờ đã chạy được ngon lành, nhưng khi nó lại cho ra 2 kết quả khác nhau. Từ 2 ví dụ trên chúng ta tạm đưa ra  kết luận là static nó có nguyên tắc gần như

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6, là đều truy xuất đến đối tượng hiện tại.

Để ok hơn nữa thì mình sẽ tiếp tục tạo ra ví dụ sau và chạy nó:

Ok, nó đã chạy được và cho ra kết quả giống với kết luận ở trên. Lúc này thì chẳng cần phải ngại ngần gì nữa mà không dám kết luận khẳng định.

Kết Luận

Self: Truy xuất đến class khai báo nó. Static: Truy xuất đến đối tượng hiện tại.

3, Lời kết.

-Như vậy mình đã giới thiệu xong đến mọi người về sự khác nhau của self và static trong PHP, ngoài ra các bạn có thể xem thêm bài so sánh giữa this và self trong PHP của mình tại đây.

4, Nguồn.

-https://toidicode.com/self-va-static-trong-php-128.html

All rights reserved

Bài viết này được dịch từ nguồn in PHP, what is the difference between self and $this? nên các ví dụ thực tế tôi xin phép được giữ nguyên từ tác giả.

Giới thiệu

Khi chúng ta làm việc với PHP, cụ thể là các PHP Framework, bạn đã từng đọc vào core của framework đó? Bạn đã từng nghe về từ khóa

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
4? Bạn đã từng sử dụng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 để gọi static function, dùng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
9 để gọi non-static function trong phạm vi class?static function, dùng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
9 để gọi non-static function trong phạm vi class?

Bạn đã bao giờ tự đặt câu hỏi dùng

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 có gọi được non-static function không? dùng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
9 có gọi được static function không? Điểm khác biệt khi dùng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 và
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
9 là gì? Tôi sẽ cùng các bạn làm rõ 2 khái niệm này thông qua bài viết hôm nay.non-static function không? dùng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
9 có gọi được static function không? Điểm khác biệt khi dùng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 và
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
9 là gì? Tôi sẽ cùng các bạn làm rõ 2 khái niệm này thông qua bài viết hôm nay.

Nhìn chung, bạn có thể hiểu rằng

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 dùng để tham chiếu đến đối tượng (object), còn
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 dùng để truy cập đến chính class. Tuy nhiên, có một vài điểm đặc trưng chi tiết hơn chúng ta sẽ bàn sâu hơn để thật sự hiểu rõ hơn về 2 khái niệm này.

Tôi sẽ đưa cho các bạn một ví dụ để dễ hình dung. Chúng ta có class Animal và một class khác Tiger kế thừa từ Animal. Class Tiger sẽ override phương thức

ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
6 của class cha. Hãy cùng xem qua cài đặt của 2 class này, đầu tiên ta sẽ dùng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6:Animal và một class khác Tiger kế thừa từ Animal. Class Tiger sẽ override phương thức
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
6 của class cha. Hãy cùng xem qua cài đặt của 2 class này, đầu tiên ta sẽ dùng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6:

class Animal {

    public function whichClass() {
        echo "I am an Animal!";
    }

    public function sayClassName() {
        $this->whichClass();
    }
}

class Tiger extends Animal {

    public function whichClass() {
        echo "I am a Tiger!";
    }

}

$tigerObj = new Tiger();
$tigerObj->sayClassName();

Ta thấy rằng ở phương thức

ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
8 của class Animal chúng ta sử dụng từ khóa
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 để gọi phương thức
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
6. Khi ta khởi tạo đối tượng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    protected static $name = 'NguoiLon';
}
// NguoiLon::getName();
$a = new NguoiLon();
$a->getName();
1 từ class
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    protected static $name = 'NguoiLon';
}
// NguoiLon::getName();
$a = new NguoiLon();
$a->getName();
2 và gọi phương thức
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
8, phương thức
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
6 của class Tiger sẽ được gọi chứ không phải phương thức
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
6 của class Animal. Do vậy kết quả ta nhận được sẽ làAnimal chúng ta sử dụng từ khóa
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 để gọi phương thức
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
6. Khi ta khởi tạo đối tượng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    protected static $name = 'NguoiLon';
}
// NguoiLon::getName();
$a = new NguoiLon();
$a->getName();
1 từ class
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    protected static $name = 'NguoiLon';
}
// NguoiLon::getName();
$a = new NguoiLon();
$a->getName();
2 và gọi phương thức
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
8, phương thức
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
6 của class Tiger sẽ được gọi chứ không phải phương thức
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
6 của class Animal. Do vậy kết quả ta nhận được sẽ là

I am a Tiger!

Lý do hết sức đơn giản, con trỏ

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 luôn luôn tham chiếu đến đối tượng hiện tại (chính là object
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    protected static $name = 'NguoiLon';
}
// NguoiLon::getName();
$a = new NguoiLon();
$a->getName();
1), và ta sẽ nhận được kết quả bằng việc gọi phương thức
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
6 của Tiger chứ không phải Animal. Nói một cách khác đây chính là ví dụ rất dễ hiểu về tính Đa hình (Polymorphism) trong PHP.Tiger chứ không phải Animal. Nói một cách khác đây chính là ví dụ rất dễ hiểu về tính Đa hình (Polymorphism) trong PHP.

Sử dụng '; echo static::$name; } } class NguoiLon extends ConNguoi { private static $name = 'NguoiLon'; } NguoiLon::getName(); 3 thay cho '; echo static::$name; } } class NguoiLon extends ConNguoi { private static $name = 'NguoiLon'; } NguoiLon::getName(); 6

Hãy cùng thử thay đổi phương thức

ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
8 trong Animal và sử dụng từ khóa
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 thay cho
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6:Animal và sử dụng từ khóa
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 thay cho
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6:

class Animal {

    public function whichClass() {
        echo "I am an Animal!";
    }

    public function sayClassName() {
        self::whichClass();
    }

}

class Tiger extends Animal {

    public function whichClass() {
        echo "I am a Tiger!";
    }

}

$tigerObj = new Tiger();
$tigerObj->sayClassName();

Về cơ bản ví dụ vẫn vậy chỉ thay đổi hết sức nhỏ. Ta sẽ thấy điều kỳ diệu xảy ra, kết quả chúng ta nhận được hoàn toàn khác với kết quả bên trên:

ConNguoi
ConNguoi
0

Điều gì đã xảy ra? Khi sử dụng

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3, bản thân nó sẽ biết mình phải gọi phương thức của chính Class chứa nó (tức là gọi hàm
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
6 của Animal). Như vậy việc sử dụng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 thông qua ví dụ trên đã ngăn chặn tính đa hình bằng việc bỏ qua

ConNguoi
NguoiLon
7. Nếu bạn muốn tìm hiểu thêm có thể tham khảo về Vtables.Animal). Như vậy việc sử dụng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 thông qua ví dụ trên đã ngăn chặn tính đa hình bằng việc bỏ qua

ConNguoi
NguoiLon
7. Nếu bạn muốn tìm hiểu thêm có thể tham khảo về Vtables.

'; echo static::$name; } } class NguoiLon extends ConNguoi { private static $name = 'NguoiLon'; } NguoiLon::getName(); 6 và '; echo static::$name; } } class NguoiLon extends ConNguoi { private static $name = 'NguoiLon'; } NguoiLon::getName(); 3 trong ngữ cảnh static function

Câu hỏi đặt ra:

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 có sử dụng được trong static function không?

Hãy cùng tìm câu trả lời thông qua một ví dụ cài đặt sau:

ConNguoi
ConNguoi
1

Kết quả nhận được:

ConNguoi
ConNguoi
2

Lỗi này xảy ra vì chúng ta đang sử dụng con trỏ

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 trong static function, tuy nhiên static function thực tế có thể được gọi mà không cần thông qua đối tượng được tạo ra từ class:

ConNguoi
ConNguoi
3

Nếu ta gọi kiểu này thì việc sử dụng con trỏ

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 ở đây không hề có ý nghĩa do con trỏ
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 tham chiếu đến đối tượng hiện tại mà với cách gọi trên không hề có một đối tượng nào chúng ta cần làm việc cùng. Trong ngữ cảnh này chúng ta sẽ gặp lỗi như trên.

Tiếp tục với việc thay sử dụng

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 bằng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3:

ConNguoi
ConNguoi
4

Đoạn code trên chạy ngon mà không hề có lỗi. Đây chính là lý do chính mà

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 được sử dụng - mục đích chính là truy cập vào thành phần tĩnh (static) trong class. Tiếp tục thực hiện một thay đổi nho nhỏ bằng việc không sử dụng static cho $name nữa:$name nữa:

ConNguoi
ConNguoi
5

Kết quả nhận được:

ConNguoi
ConNguoi
6

Lỗi này xảy ra vì chúng ta đang sử dụng con trỏ

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 trong static function, tuy nhiên static function thực tế có thể được gọi mà không cần thông qua đối tượng được tạo ra từ class:

Nếu ta gọi kiểu này thì việc sử dụng con trỏ '; echo static::$name; } } class NguoiLon extends ConNguoi { private static $name = 'NguoiLon'; } NguoiLon::getName(); 6 ở đây không hề có ý nghĩa do con trỏ '; echo static::$name; } } class NguoiLon extends ConNguoi { private static $name = 'NguoiLon'; } NguoiLon::getName(); 6 tham chiếu đến đối tượng hiện tại mà với cách gọi trên không hề có một đối tượng nào chúng ta cần làm việc cùng. Trong ngữ cảnh này chúng ta sẽ gặp lỗi như trên.

Tiếp tục với việc thay sử dụng '; echo static::$name; } } class NguoiLon extends ConNguoi { private static $name = 'NguoiLon'; } NguoiLon::getName(); 6 bằng '; echo static::$name; } } class NguoiLon extends ConNguoi { private static $name = 'NguoiLon'; } NguoiLon::getName(); 3:

Đoạn code trên chạy ngon mà không hề có lỗi. Đây chính là lý do chính mà

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 được sử dụng - mục đích chính là truy cập vào thành phần tĩnh (static) trong class. Tiếp tục thực hiện một thay đổi nho nhỏ bằng việc không sử dụng static cho $name nữa:

ConNguoi
ConNguoi
7

Lỗi xảy ra do thành phần non-static sẽ không được phép truy cập trong một static function. Có thể hiểu đơn giản là static function có thể được gọi mà không cần đối tượng từ class, những thành phần non-static thì lại cần đối tượng của class. Khái niệm này được base trên ý tưởng từ C++, các bạn muốn tìm hiểu sâu hơn có thể đọc thêm tại Accessing non static members from a static function.

ConNguoi
ConNguoi
8

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 và
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 khi truy cập những thuộc tính static và các hàm static

Tương tác với hàm static

Hãy cùng xem ví dụ cài đặt sau:

Chúng ta sử dụng

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 để gọi static function, và đương nhiên không hề có lỗi gì xảy ra. Giờ ta sẽ thay đổi một chút bằng việc sử dụng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6không nên thực hiện. Ta sẽ làm rõ hơn thông qua ví dụ sau:

ConNguoi
ConNguoi
9

Thử dự đoán xem điều gì sẽ xảy ra, có thể bạn sẽ nghĩ luôn đến việc báo lỗi trong trường hợp này. Tuy nhiên kết quả không phải như vậy, chúng ta vẫn nhận được kết quả: "I am an Animal!". Bởi vậy, chúng ta có thể gọi static function với từ khóa

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 không có vấn đề gì cả.Animal, sau đó truy cập tới phương thức sayClassName() trong đó sử dụng con trỏ $this để truy cập tới thuộc tính static name. Code này chạy không hề có lỗi và như vậy có thể kết luận việc truy cập và thay đổi giá trị của thuộc tính static bằng con trỏ $this là hoàn toàn được phép? Để làm rõ hơn vấn đề này ta lại thực hiện ví dụ sau:

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
0

Tương tác với các thuộc tích static trong Class

Sử dụng

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
1

Như ta đã thấy ở trên, việc sử dụng

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 để gọi các thành phần static không gây lỗi, tuy nhiên cách làm này không nên thực hiện. Ta sẽ làm rõ hơn thông qua ví dụ sau:

Ta khởi tạo một đối tượng $animalObj từ class Animal, sau đó truy cập tới phương thức sayClassName() trong đó sử dụng con trỏ $this để truy cập tới thuộc tính static name. Code này chạy không hề có lỗi và như vậy có thể kết luận việc truy cập và thay đổi giá trị của thuộc tính static bằng con trỏ $this là hoàn toàn được phép? Để làm rõ hơn vấn đề này ta lại thực hiện ví dụ sau:

  • Bạn thử đoán xem kết quả chúng ta nhận được sau khi lấy giá trị của $animalObj->name và $animalObj2->name có giống nhau không? Nếu thực sự có thể dùng
    ';
            echo static::$name;
        }
    }
    class NguoiLon extends ConNguoi
    {
        private static $name = 'NguoiLon';
    }
    
    NguoiLon::getName();
    
    6 để truy cập và thay đổi giá trị của thuộc tính static thì dự là ta sẽ nhận được kết quả như nhau (yaoming)
    .
  • Tuy nhiên đời không như là mơ, kết quả của echo $animalObj->name ta sẽ nhận được "My name is Animal" còn kết quả của echo $animalObj2->name sẽ báo lỗi "Undefined property". Để biết điều gì đang xảy ra tôi sẽ var_dump dữ liệu cho các bạn thấy:.

Đến đây chắc các bạn cũng hiểu được phần nào câu chuyện chúng ta đang muốn nói đến, việc gán giá trị cho thuộc tính name trong hàm setClassName() sử dụng con trỏ $this bản chất không phải chúng ta đang làm việc với thuộc tính static name mà PHP sẽ tự động tạo ra một thuộc tính non-static name (nếu chưa có) trong đối tượng $animalObj và gán giá trị cho nó. Chỉ là chúng ta có cảm giác là chúng ta đang thao tác với chính thuộc tính static mà thôi.

Như vậy có thể đưa ra một số kết luận về thuộc tính static trong PHP như sau:

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
2

Thuộc tính static không thể truy cập được thông qua object (bằng cách sử dụng ->).

Kết luận rút ra được ở đây là: trong PHP, để làm việc với các biến hay thuộc tính static, hãy dùng ngữ cảnh static (VD: dùng

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 hoặc dùng tên Class).trong PHP, để làm việc với các biến hay thuộc tính static, hãy dùng ngữ cảnh static (VD: dùng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 hoặc dùng tên Class)
.

Kết luận

Thông qua các ví dụ cụ thể hết sức thú vị, chúng ta đã hiểu hơn chút về

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 và
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 cũng như cách sử dụng chúng. Ta sẽ tổng hợp lại thông qua bảng so sánh sau:

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6
Tham chiếu đến Class hiện tại Tham chiếu đến đối tượng (Object) hiện tại
Dùng để gọi các hàm static và tham chiếu đến các thuộc tính static Có thể dùng để gọi các hàm static
Có thể dùng trong các hàm static (để truy cập đến các hàm hay thuộc tính static khác của Class) Không nên dùng để gọi các thuộc tính static (vì sẽ không truy cập được mà lại tự tạo ra các thuộc tính non-static của đối tượng), nên dùng
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 trong trường hợp này.
Khi được sử dụng sẽ ngăn chặn thể hiện của tính đa hình bằng việc bỏ qua vtable Không thể sử dụng được trong các hàm static

Hy vọng bài dịch và có chém gió thêm chút sẽ giúp các bạn hiểu hơn về

';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 và
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6.

Tài liệu tham khảo

  1. http://www.programmerinterview.com/index.php/php-questions/php-self-vs-this/