Hướng dẫn overriding in php - ghi đè trong php

Tải chồng trong PHP mang nghĩa tạo các thuộc tính và phương thức động. Những thành phần động này được xử lý thông qua các magic method được thiết lập trong một lớp với các kiểu hành động khác nhau.

Các phương thức tải chồng được gọi khi tương tác với các thuộc tính và phương thức không được khai báo hay không xuất hiện trong lớp hiện thời. Bài viết này sẽ sử dụng khai niệm "thuộc tính không thể truy cập" và "phương thức không thể truy cập" để tham chiếu tới sự kết hợp của khai báo và tầm vực.

Tất các các phương thức tải chồng phải được khai báo là public.

Chú ý:

Các tham số của các phương thức magic không được truyền bằng tham chiếu.

Khái niệm "tải chồng" của PHP khác so với phần lớn các ngôn ngữ lập trình hướng đối tượng khác. Khai niệm tải chồng truyền thống là cho phép nhiều phương thức cùng tên trong một lớp nhưng khác nhau về số lượng và kiểu của tham số.

Tải chồng thuộc tính

public void __set ( string $name , mixed $value ) void __set ( string $name , mixed $value )

public mixed __get ( string $name ) mixed __get ( string $name )

public bool __isset ( string $name ) bool __isset ( string $name )

public void __unset ( string $name ) void __unset ( string $name )

__set() được thực thi khi ghi dữ liệu tới thuộc tính không thể truy cập.

__get() được thực thi khi đọc dữ liệu từ thuộc tính không thể truy cập.

__isset() được kích hoạt bằng cách gọi isset() hoặc empty() ở những thuộc tính không thể truy cập.

__unset() được gọi đến khi unset() được sử dụng ở nhưng thuộc tính không thể truy cập.

Tham số $name là tên của thuộc tính muốn tương tác. Tham số $value của phương thức __set() xác định giá trị của thuộc tính $name được thiết lập.

Tải chồng thuộc tính chỉ làm việc với đối tượng. Những magic methods này sẽ không được kích hoạt trong trường hợp static context. Do đó những phương thức này không được khai báo là static. Ở phiên bản PHP 5.3.0 thì một cảnh báo sẽ được đưa ra nếu một sự tải chồng của magic method nào đó được khai báo là static.

Chú ý:

Các tham số của các phương thức magic không được truyền bằng tham chiếu.

Khái niệm "tải chồng" của PHP khác so với phần lớn các ngôn ngữ lập trình hướng đối tượng khác. Khai niệm tải chồng truyền thống là cho phép nhiều phương thức cùng tên trong một lớp nhưng khác nhau về số lượng và kiểu của tham số.

Tải chồng thuộc tính


class PropertyTest
{
    
/**  Nơi tải chồng dữ liệu.  */
    
private $data = array();/**  Tải chồng không sử dụng thuộc tính đã khai báo.  */
    
public $declared 1;/**  Tải chồng chỉ sử dụng khi truy cập ngoài lớp.  */
    
private $hidden 2;

    public function

__set($name$value)
    {
        echo 
"Thiết lập '$name' = '$value'\n";
        
$this->data[$name] = $value;
    }

    public function

__get($name)
    {
        echo 
"Lấy '$name'\n";
        if (
array_key_exists($name$this->data)) {
            return 
$this->data[$name];
        }
$trace debug_backtrace();
        
trigger_error(
            
'Không định nghĩa thuộc tính thông qua __get(): ' $name .
            
' trong ' $trace[0]['file'] .
            
' tại dòng ' $trace[0]['line'],
            
E_USER_NOTICE);
        return 
null;
    }
/**  Phiên bản PHP 5.1.0  */
    
public function __isset($name)
    {
        echo 
"'$name' được thiết lập?\n";
        return isset(
$this->data[$name]);
    }
/**  Phiên bản PHP 5.1.0  */
    
public function __unset($name)
    {
        echo 
"Không thiết lập '$name'\n";
        unset(
$this->data[$name]);
    }
/**  Đây không phải là magic method.  */
    
public function getHidden()
    {
        return 
$this->hidden;
    }
}

echo

"
\n";

$obj = new PropertyTest;

$obj->1;
echo 
$obj->"\n\n";

var_dump(isset($obj->a));
unset(
$obj->a);
var_dump(isset($obj->a));
echo 
"\n";

echo

$obj->declared "\n\n";

echo

"Thử nghiệm với phương thức private có tên 'hidden':\n";
echo 
"Private xuất hiện trong lớp, nên __get() không được sử dụng...\n";
echo 
$obj->getHidden() . "\n";
echo 
"Private không xuất hiện ngoài lớp, nên __get() được sử dụng...\n";
echo 
$obj->hidden "\n";
?>

__set() được thực thi khi ghi dữ liệu tới thuộc tính không thể truy cập.

__get() được thực thi khi đọc dữ liệu từ thuộc tính không thể truy cập.
Lấy 'a'
1

__isset() được kích hoạt bằng cách gọi isset() hoặc empty() ở những thuộc tính không thể truy cập.
bool(true)
Không thiết lập 'a'
'a' được thiết lập?
bool(false)

1

__unset() được gọi đến khi unset() được sử dụng ở nhưng thuộc tính không thể truy cập.
Private xuất hiện trong lớp, nên __get() không được sử dụng...
2
Private không xuất hiện ngoài lớp, nên __get() được sử dụng...
Lấy 'hidden'

Tham số $name là tên của thuộc tính muốn tương tác. Tham số $value của phương thức __set() xác định giá trị của thuộc tính $name được thiết lập.

Tải chồng thuộc tính chỉ làm việc với đối tượng. Những magic methods này sẽ không được kích hoạt trong trường hợp static context. Do đó những phương thức này không được khai báo là static. Ở phiên bản PHP 5.3.0 thì một cảnh báo sẽ được đưa ra nếu một sự tải chồng của magic method nào đó được khai báo là static.

public mixed __call ( string $name , array $arguments ) mixed __call ( string $name , array $arguments )

Giá trị trả về của __set() bị bỏ qua bởi cách thức PHP xử lý toán tử gán. Tương tự như vậy thì phương thức __get() sẽ không bao giờ được gọi khi ta thực hiện việc gán liên tiếp dạng như sau: mixed __callStatic ( string $name , array $arguments )

$a = $obj->b = 8;

Dưới đây là ví dụ về tải chồng thuộc tính thông qua các phương thức __get(), __set(), __isset() và __unset()

Output của ví dụ trên:

Thiết lập 'a' = '1'Lấy 'a'1

$value2

$value3

$value4

'a' được thiết lập?bool(true)Không thiết lập 'a''a' được thiết lập?bool(false)

Thử nghiệm với phương thức private có tên 'hidden':Private xuất hiện trong lớp, nên __get() không được sử dụng...2Private không xuất hiện ngoài lớp, nên __get() được sử dụng...Lấy 'hidden'
Gọi phương thức tĩnh 'runTest' trong trường hợp static