Proprietà in sola lettura in OOP in PHP
Consideriamo una classe in cui tutte le proprietà sono private:
<?php
class Test
{
private $prop1 = 1;
private $prop2 = 2;
}
?>
Ora rendiamo queste proprietà accessibili all'esterno solo in lettura. In precedenza abbiamo già fatto ciò, creando getter per ogni proprietà e non creando setter.
Affrontiamo ora questo problema utilizzando
il metodo magico __get. Restituiremo
in esso il valore della proprietà richiesta. Come
fare: il nome della proprietà richiesta arriva
nel parametro del metodo __get, nel nostro caso
$property.
Ciò significa che possiamo leggere la proprietà,
il cui nome è memorizzato nella variabile, in questo modo:
$this->$property (il nome della proprietà sarà
una variabile, cioè con il dollaro all'inizio,
lo abbiamo visto nelle lezioni precedenti).
Creiamo il metodo __get descritto:
<?php
class Test
{
private $prop1 = 1;
private $prop2 = 2;
public function __get($property)
{
return $this->$property;
}
}
?>
Utilizziamolo per leggere le proprietà:
<?php
$test = new Test;
echo $test->prop1; // visualizzerà 1
echo $test->prop2; // visualizzerà 2
?>
Il tentativo di scrivere qualcosa nella proprietà porterà a un errore:
<?php
$test = new Test;
$test->prop1 = 2; // darà un errore
?>
Questo è esattamente ciò di cui abbiamo bisogno: la proprietà può essere letta, ma non scritta.
Il tentativo di leggere una proprietà inesistente darà un errore:
<?php
$test = new Test;
echo $test->prop3; // darà un errore
?>
Fate anche attenzione alla seguente sfumatura: quando rendevamo le proprietà in sola lettura con il vecchio metodo, per leggere una proprietà, utilizzavamo un metodo getter.
Con il nuovo metodo accederemo direttamente alle proprietà, come se fossero pubbliche. Ma non potremo scriverci, come se fossero private.
Supponiamo di avere questa classe User, le cui proprietà
sono accessibili in sola lettura tramite
getter:
<?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;
}
}
?>
Modificate il codice di questa classe in modo che invece
dei getter venga utilizzato il metodo
magico __get.