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:

Test.php<?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ả:

Test.php<?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:

index.php<?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<?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<?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.

Задание 1

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<?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.