Trong C++ hoặc Java, thuật ngữ này có nghĩa là một lớp có thể có một phương thức lớp cùng tên nhiều hơn một lần nhưng với các đối số và/hoặc kiểu trả về khác nhau. Trong PHP, thuật ngữ này có một cách hiểu khác. Nó là một tính năng cho phép các thuộc tính và phương thức có thể được tạo ra một cách động. Các phương thức ma thuật của PHP (các tên phương thức bắt đầu bằng hai dấu gạch dưới) được sử dụng để thiết lập các thuộc tính và phương thức động.
Các phương thức ma thuật được sử dụng với mục đích quá tải sẽ được gọi khi tương tác với các thuộc tính hoặc phương thức chưa được khai báo hoặc không thể nhìn thấy trong phạm vi hiện tại.
Các ví dụ về các phương thức ma thuật của PHP là __construct(), __destruct(), __tostring(), v.v. PHP sử dụng các phương thức ma thuật sau để quá tải thuộc tính.
public __set ( string $name , mixed $value ) : void public __get ( string $name ) : mixed public __isset ( string $name ) : bool public __unset ( string $name ) : void
Ở đây,
__set() được thực thi để ghi dữ liệu vào các thuộc tính không thể truy cập, mà là được bảo vệ, riêng tư hoặc không tồn tại.
__get() đọc dữ liệu từ các thuộc tính không thể truy cập.
__isset() gọi isset() hoặc empty() trên các thuộc tính không thể truy cập.
__unset() được gọi khi unset() được gọi trên các thuộc tính không thể truy cập.
Đối số $name được sử dụng ở trên là tên của thuộc tính cần được thiết lập hoặc truy xuất. Đối số $value của phương thức __set() chỉ định giá trị sẽ được gán cho thuộc tính.
Phương thức __isset() kiểm tra xem một thuộc tính nhất định đã được thiết lập hay chưa. Phương thức __unset() xóa thuộc tính đó.
Property overloading chỉ hoạt động trong object context . Trong bất kỳ static context nào, những phương thức ma thuật này sẽ không được kích hoạt. Do đó, chúng không nên được khai báo là tĩnh.
Trong đoạn mã dưới đây, một thuộc tính động có tên là myprop, chưa được khai báo trong lớp, được thiết lập và truy xuất.
<?php class myclass { public function __set($name, $value) { echo "setting $name property to $value \n"; $this->$name = $value; } public function __get($name) { echo "value of $name property is "; return $this->$name; } } $obj = new myclass(); # This calls __set() method $obj->myproperty="Hello World!"; # This call __get() method echo "Retrieving myproperty: " . $obj->myproperty . PHP_EOL; ?>
Nó sẽ tạo ra output −
setting myproperty property to Hello World! Retrieving myproperty: Hello World!
Các phương thức ma thuật __set() và __get() cũng thiết lập và truy xuất một thuộc tính được khai báo là riêng tư. Thêm câu lệnh sau vào bên trong myclass (trước các định nghĩa hàm)
private $myproperty;
Bạn có thể kiểm tra xem thuộc tính có tồn tại hay không bằng cách định nghĩa phương thức __isset() trong myclass .
public function __isset($name) { return isset($this->$name); }
Kiểm tra xem thuộc tính có được thiết lập hay không với câu lệnh này −
var_dump (isset($obj->myproperty));
Trong trường hợp này, nó trả về true .
Để hủy thiết lập thuộc tính được tạo động với phương thức __unset() được định nghĩa trong myclass −
public function __unset($name) { unset($this->$name); }
Mã code sau sẽ trả về false −
var_dump (isset($obj->myproperty));
Hai phương thức ma thuật được sử dụng để thiết lập phương thức một cách động là __call() và __callStatic() .
public __call (string $name , array $arguments) : mixed public static __callStatic (string $name , array $arguments) : mixed
Hàm __call() được kích hoạt khi gọi các phương thức không thể truy cập (không được định nghĩa hoặc riêng tư) trong ngữ cảnh của một đối tượng. Ngược lại, hàm __callStatic() được kích hoạt khi gọi các phương thức không thể truy cập trong ngữ cảnh tĩnh.
Ví dụ sau đây minh họa việc nạp chồng phương thức (method overloading) trong PHP.
<?php class myclass { public function __call($name, $args) { // Value of $name is case sensitive. echo "Calling object method $name with " . implode(" ", $args). "\n"; } public static function __callStatic($name, $args) { echo "Calling static method $name with " . implode(" ", $args). "\n"; } } $obj = new myclass(); # This invokes __call() magic method $obj->mymethod("Hello World!"); # This invokes __callStatic() method myclass::mymethod("Hello World!"); ?>
Nó sẽ tạo ra output −
Calling object method mymethod with Hello World! Calling static method mymethod with Hello World!
Lưu ý rằng việc sử dụng toán tử " -> " có nghĩa là phương thức này là một instance method , và toán tử "::" có nghĩa là phương thức này là một static method .