Propriedades somente leitura em OOP em PHP
Vamos considerar uma classe em que todas as propriedades são privadas:
<?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:
<?php
class Test
{
private $prop1 = 1;
private $prop2 = 2;
public function __get($property)
{
return $this->$property;
}
}
?>
Vamos usá-lo para ler as propriedades:
<?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
$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
$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.
Suponha que temos a seguinte classe User, cujas propriedades
são acessíveis apenas para leitura usando
getters:
<?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.