Các thuộc tính chỉ đọc trong OOP trong PHP
Hãy xem xét một lớp trong đó tất cả các thuộc tính đều là private:
<?php
class Test
{
private $prop1 = 1;
private $prop2 = 2;
}
?>
Bây giờ hãy làm sao để các thuộc tính này chỉ có thể đọc được từ bên ngoài. Trước đây chúng ta đã làm điều này bằng cách tạo các phương thức getter cho từng thuộc tính và không tạo setter.
Bây giờ hãy sử dụng
phương thức ma thuật __get để giải quyết nhiệm vụ này.
Chúng ta sẽ trả về
giá trị của thuộc tính được yêu cầu trong đó. Cách
thực hiện: tên của thuộc tính được yêu cầu được truyền vào
tham số của phương thức __get, trong trường hợp của chúng ta là
$property.
Điều này có nghĩa là chúng ta có thể đọc thuộc tính
mà tên của nó được lưu trong một biến, như thế này:
$this->$property (tên thuộc tính sẽ là
một biến, nghĩa là có dấu $ ở đầu, chúng ta
đã học điều này trong các bài học trước).
Hãy tạo phương thức __get đã mô tả:
<?php
class Test
{
private $prop1 = 1;
private $prop2 = 2;
public function __get($property)
{
return $this->$property;
}
}
?>
Hãy sử dụng nó để đọc các thuộc tính:
<?php
$test = new Test;
echo $test->prop1; // sẽ in ra 1
echo $test->prop2; // sẽ in ra 2
?>
Nỗ lực ghi một cái gì đó vào thuộc tính sẽ dẫn đến lỗi:
<?php
$test = new Test;
$test->prop1 = 2; // sẽ báo lỗi
?>
Đây chính xác là những gì chúng ta cần: thuộc tính có thể được đọc, nhưng không thể ghi.
Nỗ lực đọc một thuộc tính không tồn tại sẽ báo lỗi:
<?php
$test = new Test;
echo $test->prop3; // sẽ báo lỗi
?>
Cũng lưu ý đến điểm tinh tế sau: khi chúng ta tạo các thuộc tính chỉ đọc bằng cách cũ, thì để đọc thuộc tính, chúng ta sử dụng phương thức getter.
Trong cách mới, chúng ta sẽ truy cập trực tiếp vào các thuộc tính, như thể chúng là public. Nhưng sẽ không thể ghi vào chúng, như thể chúng là private.
Cho lớp User sau, các thuộc tính
của nó chỉ có thể đọc được thông qua
các phương thức getter:
<?php
class User
{
private $name;
private $age;
public function __construct($name, $age)
{
$this->name = $name;
$this->age = $age;
}
public function getName()
{
return $this->name;
}
public function getAge()
{
return $this->age;
}
}
?>
Hãy sửa đổi mã của lớp này để thay vì
các getter, hãy sử dụng phương thức ma thuật
__get.