PHP 8.1: Свойства только для чтения
Расскажу о такой полезной вещи, которую собирается представить PHP 8.1 - называется свойствами только для чтения
PHP как язык постоянно меняется и развивается. Это не тот язык, который был 10 лет назад. Это все потому, что основная команда PHP постоянно совершенствует мелкие вещи, которые на первый взгляд могут показаться несущественными, но после исправления/реализации могут значительно улучшить общий опыт разработчика.
По сути, свойства «только для чтения» вводятся для смягчения языковых ограничений, связанных с отсутствием возможности объявлять свойства «только для чтения» без каких-либо ошибок.
Как это есть сейчас
До сих пор, если вы хотите сделать определенное свойство доступным только для чтения, единственное, что вы могли сделать, - это сделать его приватным (private). Возьмем следующий пример:
<?php
class Book
{
private $author;
public function __construct(
string $author
) {
$this->author = $author;
}
public function getAuthor(): string
{
return $this->author;
}
}
$book = new Book('Борис Акунин');
echo $book->author;
//или попытаемся присвоить новое значение
$book->author = 'Сергей Лукьяненко';
// Uncaught Error: Cannot access private property Book::$author
Если мы запустим приведенный выше пример, мы получим фатальную ошибку, которая говорит Uncaught Error: Cannot access private property Book::$author.
Используя этот подход, мы, безусловно, можем сделать свойства «только для чтения», но это своего рода «хак», и самая большая проблема с созданием private свойства заключается в том, что если вы хотите получить к нему доступ вне класса, вы должны определить геттер метод.
В нашем случае, если мы хотим получить доступ к свойству author, мы можем определить метод получения в классе следующим образом
public function getAuthor(): string
{
return $this->author;
}
Итак, чтобы решить эту проблему, PHP 8.1 теперь изначально вводит полнофункциональные свойства только для чтения
Свойства только для чтения в PHP 8.1
Этот RFC Никиты Попова представит возможность объявить свойство как «только для чтения» с помощью ключевого слова readlonly:
<?php
class Book
{
public readonly string $author;
public function __construct(
string $author
) {
// Legal initialization
$this->author = $author;
}
}
$book = new Book('Сергей Лукьяненко');
// Below will work fine
echo $book->author; // string(6) "Сергей Лукьяненко"
Как видите, использование readonly с public свойством позволяет получить доступ к свойству вне класса. Итак, больше нет необходимости использовать геттеры-методы для получения значения свойства.
Может быть заявлено только один раз
Однако здесь следует отметить одну вещь: свойство readonly может быть инициализировано только один раз и только из области, в которой оно было объявлено. Любое другое назначение или изменение свойства приведет к Error исключению:
$book = new Book('Борис Акунин');
$book->author = 'Сергей Лукьяненко'
// Error: Cannot modify readonly property Book::$author
Нет явного значения по умолчанию
Помимо этого, также невозможно указать явное значение по умолчанию для свойств только для чтения:
class Book
{
// Fatal error: Readonly property Book::$author cannot have default value
public readonly string $author = 'Борис Акунин';
}
Использовать только с типизированными свойствами
Модификатор readonly может быть применен только к типизированным свойствам. Причина в том, что нетипизированные свойства имеют неявное нулевое значение по умолчанию, которое считается инициализирующим назначением и может вызвать путаницу. Это можно смягчить, используя смешанный тип (mixed), который был представлен в PHP 8.0.
class Book
{
public readonly mixed $author;
}
Ну вот в принципе и все, что хотел сказать о новой функции в PHP 8.1, прогресс не стоит на месте, спасибо команде PHP :)
Что думаешь?