PHP 8.1: Свойства только для чтения

PHP 8.1: Свойства только для чтения

Readonly properties

Расскажу о такой полезной вещи, которую собирается представить 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 :)

 


Сергей Мухин

Веб-разработчик со стажем программирования более 9 лет, всегда в процессе учебы и созидания.

Есть вопросы?

Я почти всегда в режиме онлайн

Связаться со мной