Свойства только для чтения в ООП в 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.