Свойства само за четене в ООП в 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.