Lập trình PHP (Bài 2)

Bài 2: Lập Trình Hướng Đối Tượng: Tìm hiểu các phương thức magic

Ở bài trước, chúng ta đã tìm hiểu những kiến thức cơ bản về mô hình lập trình hướng đối tượng. Trong bài lần này, chúng ta sẽ tìm hiểu về các phương thức magic. Một trong những yếu tố giúp cho hướng đối tượng trở nên linh hoạt hơn rất nhiều.

 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.

Để gọi một hàm khi object bị hủy, chúng ta có sẵn phương thức magic__destruct(). Thông thường nó được sử dụng vào mục đích dọn dẹp một cái gì đó (ví dụ: đóng một kết nối cơ sở dữ liệu).

Để 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 />"; 

?>
Kết quả sẽ hiển thị như sau:

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

 
Để tránh được lỗi này, chúng ta thêm phương thức__toString()vào trong class:
<?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 />"; 

?>
Lần này, khi bạn echo object, vì trong MyClass chúng ta đã xây dựng hàm __toString() nên nó sẽ tự động được triệu gọi, và chúng ta thấy kết quả sẽ trả về như sau:
The class “MyClass” was initiated!
Using the toString method: I’m a class property!
The class “MyClass” was destroyed.
End of file.
Ngoài những phương thức magic chúng ta đã thảo luận ở đây, PHP còn cung cấp sẵn cho chúng ta một số phương thức magic khác. Để tìm hiểu thêm về danh sách các phương thức magic, bạn đọc thêm trong PHP manual.
(Còn tiếp)