Propriétés en lecture seule en POO en PHP
Examinons une classe dans laquelle toutes les propriétés sont privées :
<?php
class Test
{
private $prop1 = 1;
private $prop2 = 2;
}
?>
Maintenant, faisons en sorte que ces propriétés dans le monde extérieur soient accessibles uniquement en lecture. Nous avons déjà fait cela auparavant, en créant des getters pour chaque propriété et sans créer de setters.
Utilisons maintenant la méthode magique __get pour résoudre
cette tâche. Nous retournerons
dans celle-ci la valeur de la propriété demandée. Comment
procéder : le nom de la propriété demandée arrive
dans le paramètre de la méthode __get, dans notre cas
$property.
Cela signifie que nous pouvons lire la propriété
dont le nom est stocké dans une variable, comme ceci :
$this->$property (le nom de la propriété sera
une variable, c'est-à-dire avec un dollar au début, nous
l'avons vu dans les leçons précédentes).
Créons la méthode __get décrite :
<?php
class Test
{
private $prop1 = 1;
private $prop2 = 2;
public function __get($property)
{
return $this->$property;
}
}
?>
Utilisons-la pour lire les propriétés :
<?php
$test = new Test;
echo $test->prop1; // affichera 1
echo $test->prop2; // affichera 2
?>
Tenter d'écrire quelque chose dans la propriété conduira à une erreur :
<?php
$test = new Test;
$test->prop1 = 2; // générera une erreur
?>
C'est exactement ce dont nous avons besoin : la propriété peut être lue, mais ne peut pas être écrite.
Tenter de lire une propriété inexistante générera une erreur :
<?php
$test = new Test;
echo $test->prop3; // générera une erreur
?>
Notez également la nuance suivante : lorsque nous créions des propriétés en lecture seule avec l'ancienne méthode, pour lire la propriété, nous utilisions une méthode-getter.
Avec la nouvelle méthode, nous accéderons directement aux propriétés, comme si elles étaient publiques. Mais nous ne pourrons pas y écrire, comme si elles étaient privées.
Supposons qu'on ait la classe User suivante, dont les propriétés
sont accessibles uniquement en lecture à l'aide
de 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;
}
}
?>
Reconcevez le code de cette classe de sorte qu'au lieu
des getters, on utilise la méthode
magique __get.