1. Mở đầu
Magic method là gì ?
Là một lập trình viên PHP, chắc hẳn bạn đã ít nhất một lần nghe đến các magic method, các magic method rất hữu ích trong việc thao tác với đối tượng của PHP, vì thế tìm hiểu về magic method cũng rất quan trọng trong việc tìm hiểu về OOP trong PHP. Vậy magic method là gì ?
Magic method là các phương thức đặc biệt ghi đè hành động mặc định của PHP khi các hành động nhất định được thực hiện trên một đối tượng. Hay nói các khác, magic method giúp ta tùy biến các sự kiện khi làm việc với đối tượng.
Ưu và nhược điểm của magic method
Ưu điểm: Ta có thể thấy ngay ưu điểm của magic method là giúp ta có thể tùy biến các hành vi của đối tượng một cách linh hoạt, giúp ta làm việc với các đối tượng dễ dàng hơn, cũng vì lý do này mà một số framework hiện nay như Laravel áp dụng rất nhiều magic method, giúp cho framework trở nên rất linh hoạt và tùy biến cao.
Nhược điểm: Tuy nhiên magic method cũng có nhược điểm đó là tốc độ chậm hơn so với các phương thức bình thường.
2. Một số magic method thường gặp
PHP có rất nhiều magic method khác nhau (các bạn có thể tham khảo ở link cuối bài), trong bài viết này chúng ta sẽ điểm qua một số magic method thường gặp nhé.
__construct() và __destruct()
- construct() là một magic method rất phổ biến mà chắc hẳn ai trong chúng ta cũng biết đến nó. Hàm construct sẽ được gọi khi ta tạo mới một đối tượng, thông qua construct chúng ta có thể inject các dependency cần thiết khi khởi tạo đối tượng.
- construct() sẽ được gọi tự động mỗi khi đối tượng được tạo mới, tuy nhiên nếu ta có một class con kế thừa từ một class cha và cả hai đều định nghĩa hàm construct thì hàm construct của class cha sẽ không được thực hiện. Để thực hiện được hàm khởi tạo của class cha ta cần sử dụng parent::construct() bên trong hàm khởi tạo của class con. Còn nếu class không định nghĩa hàm khởi tạo thì construct sẽ được kế thừa như một phương thức bình thường, tất nhiên là hàm khởi tạo của class cha không phải private.
<?php
class Person {
protected $age;
public function __construct() {
$this->age = 10;
}
}
class Student extends Person {
protected $class;
function __construct() {
parent::__construct();
$this->class = 1;
}
}
- Ngược lại với construct() được gọi khi ta khởi tạo đối tượng thì destruct() được gọi khi ta destroy một đối tượng. Trong thực tết thì ta ít chỉ hay gặp và sử dụng construct còn destruct thì rất ít gặp nên mình chỉ nhắc qua thôi nhé.
__get() và __set()
- __get() và __set() là các phương thức rất quan trọng khi ta làm việc với các thuộc tính của đối tượng, giúp ta truy xuất và thiết lập giá trị của các thuộc tính. __get() sẽ được gọi khi ta truy cập đến một thuộc tính không được phép (private hoặc protected) hoặc không tồn tại, __get() nhận tham số là tên thuộc tính mà ta muốn truy cập đến.
- __set() sẽ được gọi khi ta gán giá trị cho các thuộc tính không được phép hoặc không tồn tại, __set() nhận tham số là tên của thuộc tính và giá trị mà ta muốn gắn cho thuộc tính đó.
public function __get($name)
{
if (property_exists($this, $name)) {
echo 'Getting ' . $name;
return $this->$name;
}
echo $name . ' is not exists';
return null;
}
public function __set($name, $value)
{
if (property_exists($this, $name)) {
echo 'Setting ' . $name . ' to ' . $value;
$this->$name = $value;
}
}
__isset() và __unset()
- __isset() được gọi khi ta sử dụng hàm isset() hoặc empty() trên các thuộc tính không thể truy cập (ptivate hoặc hoặc protected) hoặc không tồn tại.
- __unset() được gọi khi ta sử dụng hàm unset() trên các thuộc tính không thể truy cập (ptivate hoặc hoặc protected) hoặc không tồn tại.
public function __isset($name)
{
echo "Is '$name' set?\n";
return isset($this->data[$name]);
}
public function __unset($name)
{
echo "Unsetting '$name'\n";
unset($this->data[$name]);
}
__call() và __callStatic()
- __call được kích hoạt khi ta gọi đến các phương thức không thể truy cập (private hoặc proptected) của đối tượng, khá tương đồng với __get() nhưng ở đây là đối với phương thức. __call() nhận 2 tham số đầu vào, thứ nhất là tên của phương thức ta muốn gọi và tham số thứ hai là mảng các tham số của phương thức đó.
- __callStatic() cũng tương tự như __call() nhưng ở đây ta gọi đến các phương thức không thể truy cập trong ngữ cảnh tĩnh.
<?php
class MethodTest
{
public function __call($name, $arguments)
{
// Note: value of $name is case sensitive.
echo "Calling object method '$name' "
. implode(', ', $arguments). "\n";
}
public static function __callStatic($name, $arguments)
{
// Note: value of $name is case sensitive.
echo "Calling static method '$name' "
. implode(', ', $arguments). "\n";
}
}
$obj = new MethodTest;
$obj->runTest('in object context');
MethodTest::runTest('in static context');
?>
__toString()
__toString() sẽ được gọi khi object được xử lý như một chuỗi, ví dụ khi ta echo đối tượng, kết quả trả về phải là một chuỗi.
public function __toString()
{
return get_class($this);
}
3. Kết
Trên đây là một số magic method mà chúng ta sẽ gặp thường xuyên trong quá trình làm việc với PHP, trong PHP còn một số magic method khác cũng rất hữu dụng và được sử dụng rộng rãi, hãy tham khảo ở link bên dưới nhé. Hi vọng bài viết này có thể các bạn ôn lại một chút kiến thức tương đối quan trọng trong PHP, sử dụng magic method một cách hợp lý sẽ giúp code của chúng ta linh hoạt và tùy biến cao, tuy nhiên cũng không nên quá lạm dụng vì tốc độ của các magic method chậm hơn so với các method bình thường.
Nguồn tham khảo: https://www.php.net/manual/en/language.oop5.magic.php