Hướng dẫn php self static - php tự tĩnh

Hướng dẫn php self static - php tự tĩnh

Đã đă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ả

ConNguoi
ConNguoi
5 và
ConNguoi
ConNguoi
6 đề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
ConNguoi
ConNguoi
7 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ư

ConNguoi
ConNguoi
8, 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

Đã đăng vào thg 1 29, 2018 3:18 SA 3 phút đọc 3 phút đọc

Đặt vấn đề

Chúng ta cùng tìm hiểu qua một số đoạn code ví dụ như dưới đây. Giả sử chúng ta có class Car như sau :

class Car
{
    public static function model()
    {
         self::getModel();
    }

    protected static function getModel()
    {
        echo "I am a Car!";
    }

}

Ta có thể thấy method

ConNguoi
ConNguoi
9của class
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
0 là static method. Nên ta có thể sử dụng mà không cần khởi tạo đối tượng :

Car::model();

Kết quả sẽ là :

I am a Car!

Từ khóa self sẽ gọi hàm

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

NguoiLon::getName();
1 thuộc về class
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
0 và in ra dòng chữ "I am a Car" như trên. Bây giờ chúng ta sẽ tạo thêm một class gọi là class
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
3 kế thừa class
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
0 ở trên

ConNguoi
ConNguoi
0

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

NguoiLon::getName();
5 kế thưà
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 nên nó dĩ nhiên sẽ kế thừa hàm model() đã định nghĩa ở
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6. Vậy theo bạn thì điều gì sẽ xảy ra khi thay vì gọi
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
8 chúng ta sẽ gọi
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
9 như thế này ? Kết quả sẽ là :

ConNguoi
ConNguoi
1

Không phải đâu, kết quả thật sự vẫn sẽ là

ConNguoi
ConNguoi
2

Self

Vậy chuyện gì đã xảy ra ở bên trên ? Chúng ta đã gọi phương thức

ConNguoi
ConNguoi
9 từ
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
1 cơ mà ? Sao nó vẫn trả về kết quả như khi ta gọi
ConNguoi
ConNguoi
9 từ
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 ? Như ta thấy ở trên, phương thức
ConNguoi
ConNguoi
9 đã định nghĩa ở
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 đã không bị ghi đè trong
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
6. Bởi vì từ khóa
ConNguoi
ConNguoi
5 đã tham chiếu đến chính class đã định nghĩa nó (
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6) thay vì
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
1 hiện tại. Điều này dẫn đến việc nó sẽ gọi hàm
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    protected static $name = 'NguoiLon';
}
// NguoiLon::getName();
$a = new NguoiLon();
$a->getName();
0 của
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 thay vì gọi đến
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    protected static $name = 'NguoiLon';
}
// NguoiLon::getName();
$a = new NguoiLon();
$a->getName();
0 của
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
1... Trường hợp trên chả phù hợp với tính đa hình trong oop chút nào cả. Class con kế thừa class cha mà không thể nào ghi đè được nó. Và cũng vì vấn đề trên nên từ phiên bản PHP 5.3 trở đi đã cung cấp cho chúng ta một điểm mới gọi là
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    protected static $name = 'NguoiLon';
}
// NguoiLon::getName();
$a = new NguoiLon();
$a->getName();
4
Như ta thấy ở trên, phương thức
ConNguoi
ConNguoi
9 đã định nghĩa ở
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 đã không bị ghi đè trong
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
6. Bởi vì từ khóa
ConNguoi
ConNguoi
5 đã tham chiếu đến chính class đã định nghĩa nó (
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6) thay vì
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
1 hiện tại. Điều này dẫn đến việc nó sẽ gọi hàm
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    protected static $name = 'NguoiLon';
}
// NguoiLon::getName();
$a = new NguoiLon();
$a->getName();
0 của
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 thay vì gọi đến
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    protected static $name = 'NguoiLon';
}
// NguoiLon::getName();
$a = new NguoiLon();
$a->getName();
0 của
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
1...
Trường hợp trên chả phù hợp với tính đa hình trong oop chút nào cả. Class con kế thừa class cha mà không thể nào ghi đè được nó. Và cũng vì vấn đề trên nên từ phiên bản PHP 5.3 trở đi đã cung cấp cho chúng ta một điểm mới gọi là
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    protected static $name = 'NguoiLon';
}
// NguoiLon::getName();
$a = new NguoiLon();
$a->getName();
4

Static và Late static bindings

Bây giờ ở class Car ta thực hiện một thay đổi nho nhỏ. Thay vì dùng từ khóa

ConNguoi
ConNguoi
5 ta đổi nó thành
ConNguoi
ConNguoi
6 như sau

ConNguoi
ConNguoi
3

Và thực hiện lại lời gọi hàm

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

NguoiLon::getName();
9 ta sẽ thấy kết quả trả về như ta mong muốn :

ConNguoi
ConNguoi
1

Đây chính là cái gọi là late static binding trong PHP. Khi sử dụng từ khoá

ConNguoi
ConNguoi
6 thay vì
ConNguoi
ConNguoi
5, thì khi ta gọi một static funcion, nó sẽ tham chiếu đến class mà nó được gọi thay vì class đã định nghĩa nó như khi ta dùng từ khóa
ConNguoi
ConNguoi
5. Trong trường hợp này, ta gọi
ConNguoi
ConNguoi
9 từ
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
1 nên nó tham chiếu đến
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
1 và sẽ gọi đến
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    protected static $name = 'NguoiLon';
}
// NguoiLon::getName();
$a = new NguoiLon();
$a->getName();
0 của

ConNguoi
NguoiLon
5 thay vì
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 như ở trường hợp ta sử dụng từ khóa
ConNguoi
ConNguoi
5
Trong trường hợp này, ta gọi
ConNguoi
ConNguoi
9 từ
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
1 nên nó tham chiếu đến
ConNguoi

Fatal error: Cannot access private property NguoiLon::$name
1 và sẽ gọi đến
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    protected static $name = 'NguoiLon';
}
// NguoiLon::getName();
$a = new NguoiLon();
$a->getName();
0 của

ConNguoi
NguoiLon
5 thay vì
';
        echo static::$name;
    }
}
class NguoiLon extends ConNguoi
{
    private static $name = 'NguoiLon';
}

NguoiLon::getName();
6 như ở trường hợp ta sử dụng từ khóa
ConNguoi
ConNguoi
5

Kết luận

Qua bài viết nhỏ trên mình xin phân biệt sự khác nhau giữa "self" và "static" trong PHP. Mong nhận được sự góp ý, chỉnh sửa từ mọi người...

Đã đăng ký Bản quyền