Late static binding trong PHP
Trong PHP 5.3 ngoài các tính năng mới như namespace, closure được giới thiệu thì còn một tính năng nữa ít được chú ý hơn (ít nhất là mình nhận thấy vậy) đó là late static binding. Thì đầu tiên chúng ta cần phải biết late static binding là gì? Cái này mình cũng không biết giải thích sao nữa. Thôi ...
Trong PHP 5.3 ngoài các tính năng mới như namespace, closure được giới thiệu thì còn một tính năng nữa ít được chú ý hơn (ít nhất là mình nhận thấy vậy) đó là late static binding.
Thì đầu tiên chúng ta cần phải biết late static binding là gì? Cái này mình cũng không biết giải thích sao nữa. Thôi chúng ta sẽ theo dõi một ví dụ về giới hạn của self.
<?php abstract class AbstractWriter { protected static $instance; public static function getInstance() { if (! self::$instance) { self::$instance = new self(); } return self::$instance; } } class FileWriter extends AbstractWriter { } $writer = FileWriter::getInstance();
Khi các bạn chạy tới dòng lệnh $writer = FileWriter::getInstance(); bạn sẽ nhận được một fatal error về việc không thể khởi tạo một class abstract. Như các bạn đã biết từ khóa self dùng để là từ khóa gọi các phương thức tĩnh, hoặc các const được define trong Class đó hoặc các class mà nó kế thừa. Nhưng nó không thể gọi được các phương thức được define trong class con. Bạn có thể xem tiếp ví dụ sau.
<?php class Foo { protected static $name = 'foo'; public static function getName() { return self::$name; } } class Bar extends Foo { protected static $name = 'bar'; } echo Foo::getName(); echo '<br />'; echo Bar::getName();
Khi các bạn chạy thử ví dụ này sẽ thấy 2 chữ foo, tại sao không phải là foo và bar? vì đây chính là giới hạn của self. nó chỉ có thể truy cập vào được các phương thức, biến, hằng được định nghĩa trong class đó và của các class mà nó kế thừa, chứ không thể truy cập được vào các class kế thừa từ class đó. Để giải quyết vấn đề này thì từ khóa static đã được đưa vào. Giờ hãy viết lại 2 ví dụ trên và sử dụng từ khóa static nhé.
<?php abstract class AbstractWriter { protected static $instance; public static function getInstance() { if (! static::$instance) { static::$instance = new static(); } return static::$instance; } } class FileWriter extends AbstractWriter { } $writer = FileWriter::getInstance(); echo get_class($writer); echo '<br />'; class Foo { protected static $name = 'foo'; public static function getName() { return static::$name; } } class Bar extends Foo { protected static $name = 'bar'; } echo Foo::getName(); echo '<br />'; echo Bar::getName();
Kết quả bạn nhận được sẽ là
FileWriter foo bar
Tất nhiên bạn cũng có thể dùng từ khóa static cho constant