[Перевод] Депрекации в грядущем PHP 8.2, о которых вам следует знать

77b372ca5e3a4184e1975d02b8e2a8d0.png

Если вы не читали мою предыдущую статью о нововведениях в php 8.2, вы можете найти ее здесь.

Команда PHP не перестает добавлять новые фичи и исправления с каждым релизом. Но одними фичами и исправлениями дело не обходится. Иногда команде приходится принимать трудное решение отказаться от чего-либо, чтобы стандартизировать язык. Мы называем это депрекацией (deprecation), а про таковые фичи иногда говорим, что они устарели. И PHP 8.2 не станет исключением. В нем есть несколько важных депрекаций.

Динамические свойства

В классах PHP можно динамически присваивать значения свойствам, которые вы не указывали во время объявления класса, тем самым добавляя их после создания класса.

class FooBar {
    public string $bar;
}

$fooBar = new FooBar();
$fooBar->foo = 'Foo';

Вы можете предотвратить такое поведение только с помощью __set() и __get().

В PHP 8.2 и более поздних версиях присвоение значений необъявленному свойству класса считается устаревшим и выдает соответствующее уведомление о депрекации при первой установке свойства в рамках работы приложения.

class FooBar {
    public string $bar;
}
$fooBar = new FooBar();
$fooBar->foo = 'Foo';

Этот код генерирует уведомление о депрекации, как показано ниже:

Deprecated: Creation of dynamic property FooBar::$foo is deprecated in ... on line ...

В PHP 9 это уже вызовет критическую ошибку.

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

Проблема заключается в том, что многие библиотеки и фреймворки полагаются на динамические свойства. Возьмем, к примеру, Laravel Eloquent ORM, который очень сильно зависит от динамических свойств для своих свойств и взаимосвязей. Таким образом, из-за этой депрекации в фреймворке Laravel придется многое переписывать.

В рамках этой депрекации есть три исключения:

1. Классы с атрибутом #[AllowDynamicProperties].

С помощью этого нового атрибута, представленного в PHP 8.2, вы можете запретить PHP генерировать уведомление о депрекации. Это поведение унаследуют также и дочерние классы.

2. stdClass и его подклассы

В stdClass атрибут #[AllowDynamicProperties] определен по умолчанию, поэтому stdClass и любой из его наследников будут разрешать динамические свойства без каких-либо дополнительных действий с вашей стороны.

3. Классы с магическими методами __get и __set

Если в классе определен магический метод __set(), эта депрекация на него не повлияет. Вы также можете добавить метод __get() для создания практически полезного класса.

class FooBar {
    public function __set(string $name, mixed $value): void {}
}
$fooBar = new FooBar();
$fooBar->foo = 'Foo';

Но установка динамических свойств в __set() прежнему не разрешена.

class FooBar {
    public function __set(string $name, mixed $value): void {
        $this->{$name} = $value;
    }
}
$fooBar = new FooBar();
$fooBar->foo = 'foo';

То, что мы делаем выше, не разрешено, потому что мы устанавливаем динамические свойства в __set(). В результате будет сгенерировано то же уведомление о депрекации:

Deprecated: Creation of dynamic property FooBar::$foo is deprecated in ... on line ...

Частично-поддерживаемые callable 

PHP 8.2 объявляет устаревшими некоторые виды callable, которые не работают в виде  $callable().

Незатронутые виды callable

$callable = 'strlen';
$callable = ['MyClass', 'myMethod'];
$callable = 'MyClass::myMethod'];
$callable = Closure::fromCallable();
$callable = [$this, 'myMethod'];
$callable = [new MyClass(), 'myMethod'];
$callable = strlen(...);

Эти виды callable будут работать без каких-либо уведомлений о депрекации.

Устаревшие виды callable

$callable = "self::method";
$callable = "parent::method";
$callable = "static::method";
$callable = ["self", "method"];
$callable = ["parent", "method"];
$callable = ["static", "method"];
$callable = ["MyClass", "MyParentClass::myMethod"];
$callable = [new MyClass(), "MyOtherClass::myMethod"];

Если вы попытаетесь использовать callable вида, подобного приведенным выше, то увидите уведомление о депрекации.

Mbstring: кодировки Base64, Uuencode, QPrint и HTML Entity

Расширение PHP Multi-Byte Strings (mbstring) добавляет функционал для работы со строками PHP, содержащими многобайтовые символы, такие как символы азиатских письменностей, эмодзи и тысячи других символов, которые не могут поместиться в один байт.

В PHP 8.2 использование расширения Mbstring для кодирования/декодирования строк в Base64, Quoted-Printable, Uuencode и HTML Entities подверглось депрекации.

Это касается следующих кодировок. Сокращенные названия кодировок нечувствительны к регистру.

BASE64
UUENCODE
HTML-ENTITIES
html (alias of HTML-ENTITIES)
Quoted-Printable
qprint (alias of Quoted-Printable)

Причина этого в том, что ядро ​​PHP уже предоставляет альтернативу для этих функций. Например:

mb_convert_encoding('test', 'base64'));

Вы можете сделать тоже самое, используя base64_encode('test').

Здесь вы можете узнать об этом больше

Интерполяция строк вида ${var}

В PHP можно заменить переменную в строковом литерале с помощью двойных кавычек и heredoc-синтаксиса.

$name = 'PHP';
echo "Hello $name"; // Hello PHP

Для лучшей читабельности вы также можете выделить переменную фигурными скобками ({}). PHP также поддерживает знак доллара за пределами фигурных скобок.

echo "Hello ${name}";

Но в php 8.2 это наконец устарело.

Deprecated: Using ${var} in strings is deprecated, use {$var} instead in ... on line ...

Недавно прошел открытый мастер-класс курса «PHP Developer. Professional» на тему «Разработка одностраничного приложения на PHP с помощью Symfony и Vue.js». Приглашаем всех желающих посмотреть его в записи.

© Habrahabr.ru