Свойства само за четене в ООП в PHP
Нека разгледаме клас, в който всички свойства са приватни:
<?php
class Test
{
private $prop1 = 1;
private $prop2 = 2;
}
?>
Сега нека направим така, че тези свойства в външния свят да са достъпни само за четене. Преди вече сме правили такова нещо, създавайки гетъри за всяко свойство и без да създаваме сетъри.
Сега за решаване на тази задача ще използваме
магическия метод __get. Ще връщаме
в него стойността на поисканото свойство. Как
да го направим: името на поисканото свойство попада
в параметъра на метода __get, в нашия случай
$property.
Това означава, че можем да прочетем свойство,
чието име се съхранява в променлива, ето така:
$this->$property (името на свойството ще бъде
променлива, тоест с долар в началото, ние
това сме го учили в предишните уроци).
Нека направим описания метод __get:
<?php
class Test
{
private $prop1 = 1;
private $prop2 = 2;
public function __get($property)
{
return $this->$property;
}
}
?>
Нека го използваме за четене на свойства:
<?php
$test = new Test;
echo $test->prop1; // ще изведе 1
echo $test->prop2; // ще изведе 2
?>
Опитът да запишем нещо в свойството ще доведе до грешка:
<?php
$test = new Test;
$test->prop1 = 2; // ще даде грешка
?>
Това е точно това, от което се нуждаем: свойството може да се чете, но не може да се записва.
Опитът да се прочете несъществуващо свойство ще даде грешка:
<?php
$test = new Test;
echo $test->prop3; // ще даде грешка
?>
Обърнете внимание и на следния нюанс: когато правихме свойства само за четене по стария начин, то за да прочетем свойство, използвахме метод-гетър.
В новия начин ние ще се обръщаме именно към свойствата, сякаш са публични. Но да запишем в тях няма да можем, сякаш са приватни.
Нека е даден следният клас User, свойствата
на който са достъпни само за четене с помощта
на гетъри:
<?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.