Propriedades somente leitura em OOP em PHP

Vamos considerar uma classe em que todas as propriedades são privadas:

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

Agora, vamos fazer com que essas propriedades no mundo externo fiquem acessíveis apenas para leitura. Já fizemos isso antes, criando getters para cada propriedade e não criando setters.

Vamos agora usar para resolver essa tarefa o método mágico __get. Vamos retornar nele o valor da propriedade solicitada. Como fazer isso: o nome da propriedade solicitada chega no parâmetro do método __get, no nosso caso $property.

Isso significa que podemos ler a propriedade, cujo nome está armazenado em uma variável, assim: $this->$property (o nome da propriedade será uma variável, ou seja, com o cifrão no início, nós já vimos isso em lições anteriores).

Vamos criar o método __get descrito:

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

Vamos usá-lo para ler as propriedades:

index.php<?php
  $test = new Test;
  
  echo $test->prop1; // exibirá 1
  echo $test->prop2; // exibirá 2
?>

A tentativa de escrever algo na propriedade levará a um erro:

php<?php
  $test = new Test;
  $test->prop1 = 2; // dará um erro
?>

Isso é exatamente o que precisamos: a propriedade pode ser lida, mas não pode ser escrita.

A tentativa de ler uma propriedade inexistente dará um erro:

php<?php
  $test = new Test;
  echo $test->prop3; // dará um erro
?>

Observe também a seguinte nuance: quando fazíamos propriedades somente leitura da maneira antiga, para ler a propriedade, usávamos um método getter.

Na nova maneira, vamos acessar exatamente as propriedades, como se fossem públicas. Mas não poderemos escrever nelas, como se fossem privadas.

Задание 1

Suponha que temos a seguinte classe User, cujas propriedades são acessíveis apenas para leitura usando getters:

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

Refatore o código desta classe para que, em vez de getters, seja usado o método mágico __get.