Что нового в PHP 8.2

Что нового в PHP 8.2

PHP 8.2 будет выпущен примерно в конце 2022 года, но точно пока неизвестно. В этом посте мы рассмотрим все функции, улучшения производительности, изменения и устаревший функционал

null и false как самостоятельные типы rfc

Не вдаваясь в тему безопасности типов, технически null и false, сами по себе могут считаться допустимыми типами. Типичными примерами являются встроенные функции PHP, где false используется в качестве возвращаемого типа при возникновении ошибки. Например в file_get_contents:


file_get_contents(/* … */): string|false

Обратите внимание, что использование false в типе объединения уже было ранее возможным, но в PHP 8.2 его можно использовать и как отдельный тип:


function alwaysFalse(): false
{
return false;
}

Что интересно данный RFC не поддерживает true как отдельный тип, да и разве типы не должны представлять в целом категории вместо отдельных значений? Оказывается, в системах типов существует концепция, называемая единичным типом, то есть тип, допускающий только одно значение. Но действительно ли это полезно и поощряет ли это чистый дизайн приложения? Может быть, а может и нет.

Автономный null тип имеет немного больше смысла: null может рассматриваться как категория сама по себе, а не просто значение внутри категории. Представьте себе шаблон нулевого объекта: 

class Post 
{
public function getAuthor(): ?string { /* … */ }
}

class NullPost extends Post
{
public function getAuthor(): null { /* … */ }
}

 

NullPost::getAuthor() всегда будет возвращать только null, а не null или string, что раньше было невозможно.

Устаревшие динамические свойства rfc

Динамические свойства устарели в PHP 8.2 и будут выдавать ошибку ErrorException в PHP 9.0. Если вы не знаете, что такое динамические свойства, то это свойства, которые не присутствуют в объекте, но тем не менее присваиваются или запрашиваются:


class Post
{
public string $header;
}

// …

$post->title = 'Заголовок';

Имейте в виду, что классы реализующие __get и __set будут работать по назначению: 


class Post
{
private array $properties = [];

public function __set(string $title, mixed $value): void
{
$this->properties[$title] = $value;
}
}

То же самое касается объектов stdClass, они будут поддерживать динамические свойства.

Если вам не нужны эти предупреждения при обновлении до PHP 8.2, вы можете сделать пару вещей.

Вы можете использовать атрибут для классов, которые должны разрешать эти свойства: #[AllowDynamicProperties]


#[AllowDynamicProperties]
class Post
{
public string $header;
}

// …

$post->title = 'Заголовок'; //Все пройдет нормально

Другой вариант — просто отключить предупреждения об устаревших функциях. Я бы не рекомендовал этого делать, так как у вас будут проблемы с PHP 9.0, но вот как вы все равно можете отключить предупреждения об устаревании в PHP: 


error_reporting(E_ALL ^ E_DEPRECATED);

Редактирование параметров в бэк трейсах rfc

Обычной практикой в ​​любой кодовой базе является отправка производственных ошибок в службу, которая их отслеживает и уведомляет разработчиков, когда что-то пойдет не так. Эта практика часто включает отправку трассировки стека по сети в стороннюю службу. Однако бывают случаи, когда эти трассировки стека могут включать конфиденциальную информацию, такую ​​как переменные среды, пароли или имена пользователей.

PHP 8.2 позволяет вам помечать такие «конфиденциальные параметры» атрибутом, так что вам не нужно беспокоиться о том, что они будут перечислены в вашей трассировке стека, когда что-то пойдет не так. Вот пример из RFC:


function test(
$foo,
#[SensitiveParameter] $bar,
$baz
) {
throw new Exception('Error');
}

test('foo', 'bar', 'baz');


Fatal error: Uncaught Exception: Error in test.php:8
Stack trace:
#0 test.php(11): test('foo', Object(SensitiveParameterValue), 'baz')
#1 {main}
thrown in test.php on line 8

Устаревшие частично поддерживаемые вызываемые объекты rfc  

Еще одно изменение, хотя и с немного меньшим влиянием, заключается в том, что частично поддерживаемые вызываемые объекты теперь также устарели. Частично поддерживаемые вызываемые объекты — это вызываемые объекты, которые можно вызывать с помощью call_user_func($callable), но не напрямую $callable(). Между прочим, список этих видов коллбеков довольно короткий:

"self::method"
"parent::method"
"static::method"
["self", "method"]
["parent", "method"]
["static", "method"]
["Foo", "Bar::method"]
[new Foo, "Bar::method"]

Причина для этого - шаг в правильном направлении к возможности использования типизированных свойств callable. Никита очень хорошо объясняет это в RFC:

Все эти вызываемые объекты зависят от контекста. Метод, на который ссылается «self::method», зависит от того, из какого класса выполняется вызов или проверка возможности вызова. На практике это обычно справедливо и для последних двух случаев, когда используется [new Foo, "parent::method"].
Уменьшение зависимости вызываемых объектов от контекста является вторичной целью этого RFC. После этого RFC единственная оставшаяся зависимость от области видимости — это видимость метода: «Foo::bar» может быть виден в одной области видимости, но не в другой. Если бы в будущем вызываемые объекты были ограничены public методами (в то время как private методы должны были бы использовать вызываемые объекты первого класса или Closure::fromCallable(), чтобы сделать их независимыми от области видимости), то вызываемый тип стал бы четко определенным и мог бы использоваться как тип свойства. Однако изменения в обработке видимости не предлагаются как часть этого RFC. 


Независимая от локали конвертация регистра rfc

Некоторые изменения в том, как работает преобразование регистра, теперь не зависят от локали.


Сергей Мухин

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

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

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

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