Свойства только для чтения в ООП в PHP

Давайте рассмотрим класс, в котором все свойства приватные:

Test.php<?php
  class Test
  {
    private $prop1 = 1;
    private $prop2 = 2;
  }
?>

Теперь сделаем так, чтобы эти свойства во внешнем мире были доступны только для чтения. Ранее мы такое уже делали, создавая геттеры для каждого свойства и не создавая сеттеры.

Давайте теперь для решения этой задачи воспользуемся магическим методом __get. Будем возвращать в нем значение запрошенного свойства. Как это сделать: имя запрошенного свойства попадает в параметр метода __get, в нашем случае $property.

Это значит, что мы можем прочитать свойство, имя которого хранится в переменной, вот так: $this->$property (имя свойства будет переменной, то есть с долларом вначале, мы это проходили в предыдущих уроках).

Давайте сделаем описанный метод __get:

Test.php<?php
  class Test
  {
    private $prop1 = 1;
    private $prop2 = 2;
    
    public function __get($property)
    {
      return $this->$property;
    }
  }
?>

Воспользуемся им для чтения свойств:

index.php<?php
  $test = new Test;
  
  echo $test->prop1; // выведет 1
  echo $test->prop2; // выведет 2
?>

Попытка записать что-то в свойство приведет к ошибке:

php<?php
  $test = new Test;
  $test->prop1 = 2; // выдаст ошибку
?>

Это именно то, что нам нужно: свойство можно прочитывать, но нельзя записывать.

Попытка прочитать несуществующее свойство выдаст ошибку:

php<?php
  $test = new Test;
  echo $test->prop3; // выдаст ошибку
?>

Обратите также внимание на следующий нюанс: когда мы делали свойства только для чтения старым способом, то для того, чтобы прочитать свойство, мы использовали метод-геттер.

В новом способе мы будем обращаться именно к свойствам, будто они публичные. Но записать в них не сможем, будто они приватные.

Задание 1

Пусть дан вот такой класс User, свойства которого доступны только для чтения с помощью геттеров:

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;
    }
  }
?>

Переделайте код этого класса так, чтобы вместо геттеров использовался магический метод __get.