Bài 2: Lập Trình Hướng Đối Tượng: Tìm hiểu các phương thức magic
Phương Thức Magic Trong OOP
Để giúp cho việc sử dụng các object trở nên thuận tiện hơn, PHP đã cung cấp một số phương thức magic, chúng thường được gọi khi có những action nhất định thường xuyên xảy ra trong các object. Điều này cho phép lập trình viên thực thi một số tác vụ hữu ích dễ dàng.
Sử dụng Constructors (hàm dựng) và Destructors (hàm hủy)
Khi một object được khởi tạo, nó thường kèm theo nhu cầu thiết lập một vài thứ ngoài lề. Để xử lý điều này, PHP cung cấp phương thức magic__construct(), phương thức này sẽ tự động được gọi ngay khi một object mới được khởi tạo.
Để minh họa cho khái niệm constructor, chúng ta sẽ thêm một hàm dựng(constructor) vào Myclasscó nhiệm vụ xuất ra một thông tin bất kỳ (do chúng ta thiết lập) ngay khi có một object thể hiện của class được khởi tạo.
<?php class MyClass { public $prop1 = "I'm a class property!"; public function __construct() { echo 'The class "', __CLASS__, '" was initiated!<br />'; } public function setProperty($newval) { $this->prop1 = $newval; } public function getProperty() { return $this->prop1 . "<br />"; } } // Tạo object $obj = new MyClass; // echo giá trị thuộc tính $prop1 echo $obj->getProperty(); echo "End of file.<br />"; ?>
Chú ý: __CLASS__trả về tên của chính class gọi nó; nó được gọi hằng số magic (magic constant). Trong PHP, thì có một vài hằng số magic, để tìm hiểu thêm về chúng bạn tìm đọc trong PHP manual.
Đọc lại file trên trình duyệt, bạn sẽ thấy kết quả như sau:
The class “MyClass” was initiated!
I’m a class property!
End of file.
Để minh họa, chúng ta sẽ xuất ra một đoạn thông tin khi object bị hủy bằng cách sử dụng phương thức__destruct()trong MyClass:
<?php class MyClass { public $prop1 = "I'm a class property!"; public function __construct() { echo 'The class "', __CLASS__, '" was initiated!<br />'; } public function __destruct() { echo 'The class "', __CLASS__, '" was destroyed.<br />'; } public function setProperty($newval) { $this->prop1 = $newval; } public function getProperty() { return $this->prop1 . "<br />"; } } // Tạo object $obj = new MyClass; // Echo giá trị thuộc tính $prop1 echo $obj->getProperty(); echo "End of file.<br />"; ?>
Với một hàm hủy được định nghĩa trong class, bạn reload lại trình duyệt để nhận được kết quả như sau:
The class “MyClass” was initiated!
I’m a class property!
End of file.
The class “MyClass” was destroyed.
“Khi kết thúc một file, PHP sẽ tự động giải phóng mọi tài nguyên.”
Vì vậy, để hiểu rõ bản chất hàm hủy hơn, chúng ta sẽ hủy object trước khi kết thúc file bằng hàm unset():
<?php class MyClass { public $prop1 = "I'm a class property!"; public function __construct() { echo 'The class "', __CLASS__, '" was initiated!<br />'; } public function __destruct() { echo 'The class "', __CLASS__, '" was destroyed.<br />'; } public function setProperty($newval) { $this->prop1 = $newval; } public function getProperty() { return $this->prop1 . "<br />"; } } // Tạo object $obj = new MyClass; // Echo giá trị thuộc tính $prop1 echo $obj->getProperty(); // Hủy object unset($obj); echo "End of file.<br />"; ?>
Bây giờ kết quả trên trình duyệt sẽ hiển thị như sau:
The class “MyClass” was initiated!
I’m a class property!
The class “MyClass” was destroyed.
End of file.
Convert qua một Chuỗi
Nếu bạn muốn echo MyClass ra dưới dạng chuỗi, bạn sẽ gặp lỗi. Để tránh được lỗi này, bạn cần sử dụng một phương thức magic khác được gọi là__toString().
Nếu không có__toString(), mọi cố gắng để echo object ra dưới dạng chuỗi sẽ đều cho ra một kết quả lỗi nghiêm trọng (fatal error). Dưới đây là một ví dụ về việc echo một object ra dưới dạng chuỗi mà không sử dụng một phương thức magic:
<?php class MyClass { public $prop1 = "I'm a class property!"; public function __construct() { echo 'The class "', __CLASS__, '" was initiated!<br />'; } public function __destruct() { echo 'The class "', __CLASS__, '" was destroyed.<br />'; } public function setProperty($newval) { $this->prop1 = $newval; } public function getProperty() { return $this->prop1 . "<br />"; } } // Tạo object. $obj = new MyClass; // Echo object ra dưới dạng một chuỗi echo $obj; // Hủy object unset($obj); echo "End of file.<br />"; ?>
The class “MyClass” was initiated!
Catchable fatal error: Object of class MyClass could not be converted to string in /Applications/XAMPP/xamppfiles/htdocs/testing/test.php on line 40
<?php class MyClass { public $prop1 = "I'm a class property!"; public function __construct() { echo 'The class "', __CLASS__, '" was initiated!<br />'; } public function __destruct() { echo 'The class "', __CLASS__, '" was destroyed.<br />'; } public function __toString() { echo "Using the toString method: "; return $this->getProperty(); } public function setProperty($newval) { $this->prop1 = $newval; } public function getProperty() { return $this->prop1 . "<br />"; } } // Tạo object $obj = new MyClass; // Echo object ra dưới dạng một chuỗi echo $obj; // Hủy object unset($obj); echo "End of file.<br />"; ?>
Using the toString method: I’m a class property!
The class “MyClass” was destroyed.
End of file.