Что нового в PHP 8.1

Kate

Administrator
Команда форума
Версия PHP 8.1 находится в активной разработке и будет выпущена 25 ноября 2021 г. Следует иметь в виду, что эта дата может измениться, если основная команда разработчиков решит, например, добавить дополнительный бета-выпуск. Мы уже знаем о новых возможностях, повышении производительности, изменениях и упразднении сомнительной функциональности. Давайте рассмотрим эти новшества по порядку.

Новые возможности​

Как и в каждом выпуске, в PHP 8.1 добавлено несколько новых полезных возможностей. Имейте в виду, что в течение года этот список будет пополняться.

Перечисления rfc​

В PHP 8.1 будут добавлены перечисления (enum)! Если вы не уверены, зачем они нужны, можете прочитать о них здесь.

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

enum Status {
case Pending;
case Active;
case Archived;
}
И вот как они будут использоваться:

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

Файберы rfc​

Файберы (fiber), или «зеленые потоки», представляют собой низкоуровневый механизм управления параллелизмом. Возможно, вам не придется использовать их в своих приложениях напрямую, но они будут широко применяться такими фреймворками, как Amphp и ReactPHP.

Вот простой пример использования файберов:

$fiber = new Fiber(function (): void {
$valueAfterResuming = Fiber::suspend('после приостановки');

// …

});

$valueAfterSuspending = $fiber->start();

$fiber->resume('после возобновления');
Если вы хотите узнать больше о файберах и о том, что они могут и чего не могут делать, прочтите эту статью.

Повышение производительности pr​

Дмитрий Стогов добавил в opcache ряд улучшений, назвав их кешем наследования (inheritance cache). Эта возможность позволяет кешировать связи между классами и очень похожа на предзагрузку связанных классов в PHP 7.4.

Дмитрий сообщает, что в результате производительность повышается на 5–8 %, — одна из приятных мелочей, ожидаемых от PHP 8.1.

Распаковка массивов со строковыми ключами rfc​

Распаковка массивов была доступна еще в PHP 7.4, но работала только с числовыми ключами. Строковые ключи не поддерживались, так как не было единого мнения относительно объединения дубликатов в массивах. В данном RFC эта проблема четко решается путем следования семантике array_merge:

$array1 = ["a" => 1];

$array2 = ["b" => 2];

$array = ["a" => 0, ...$array1, ...$array2];

var_dump($array); // ["a" => 1, "b" => 2]

Новый тип never rfc​

Тип never можно использовать для указания того, что функция будет останавливать поток выполнения программы. Это можно сделать вызовом исключения или функции exit либо подобных ей.

function dd(mixed $input): never
{
// dump

exit;
}
never отличается от void тем, что void позволяет программе продолжить выполнение. Этот тип может показаться необычным новшеством, но на деле он будет весьма полезен для статических анализаторов.

Новая функция array_is_list rfc​

Возможно, вы имели дело с задачами, когда нужно было определить, представляют ли ключи массива числовую последовательность 0, 1, 2, 3..., подобно тому, как функция json_encode определяет, следует ли кодировать массив как массив или как объект.

В PHP 8.1 добавлена встроенная функция для определения того, является ли массив списком с такой семантикой или нет:

$list = ["a", "b", "c"];

array_is_list($list); // true

$notAList = [1 => "a", 2 => "b", 3 => "c"];

array_is_list($notAList); // false

$alsoNotAList = ["a" => "a", "b" => "b", "c" => "c"];

array_is_list($alsoNotAList); // false

Финальные константы классов rfc​

Константы классов в PHP могут быть переопределены при наследовании:

class Foo
{
public const X = "foo";
}

class Bar extends Foo
{
public const X = "bar";
}
Начиная с PHP 8.1 такие константы можно помечать словом final, чтобы исключить эту возможность:

class Foo
{
final public const X = "foo";
}

class Bar extends Foo
{
public const X = "bar";
Fatal error: Bar::X cannot override final constant Foo::X
}

Новая функция fsync rfc​

В PHP 8.1 добавлены функции fsync и fdatasync, выполняющие перед возвратом принудительную синхронизацию изменений файла с диском и обеспечивающие очистку буферов записи операционной системы.

$file = fopen("sample.txt", "w");

fwrite($file, "Какое-то содержимое");

if (fsync($file)) {
echo "Файл успешно сохранен на диск.";
}

fclose($file);
Поскольку синхронизация c диском — это операция файловой системы, функция fsync будет работать только с обычными файловыми потоками. При попытке синхронизации нефайловых потоков будет выдаваться предупреждение.

Явная нотация восьмеричных целочисленных литералов rfc​

Теперь для обозначения восьмеричных чисел можно использовать префиксы 0o и 0O. Ранее принятая нотация, согласно которой к числу следовало добавлять префикс 0, также по-прежнему будет работать.

016 === 0o16; // true

016 === 0O16; // true

Изменения, которые могут затронуть существующий код​

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

Ограничение использования $GLOBALS rfc​

Небольшое изменение условий работы с массивом $GLOBALS существенно повлияет на производительность всех операций с массивами. Никита Попов отлично объяснил проблему и ее решение в соответствующем RFC. Суть изменения в том, что с массивом $GLOBALS теперь нельзя будет выполнять некоторые редко используемые операции. «Перезапись $GLOBALS как единого целого отныне не поддерживается. Все приведенные ниже инструкции вызовут ошибку во время компиляции»:

$GLOBALS = [];

$GLOBALS += [];

$GLOBALS =& $x;

$x =& $GLOBALS;

unset($GLOBALS);
Кроме того, передача $GLOBALS по ссылке будет вызывать ошибку времени выполнения:

by_ref($GLOBALS); // Ошибка времени выполнения
Никита проанализировал 2000 самых популярных пакетов на Packagist и обнаружил только 23 случая, на которые повлияет это изменение. Можно сделать вывод, что влияние этого формально критического изменения будет незначительным, поэтому было решено добавить его в PHP 8.1. Следует отметить, что большая часть разработчиков от этого только выиграет, поскольку оно положительно повлияет на производительность кода.

Переход от ресурсов к объектам​

Эти изменения являются частью долгосрочной стратегии преобразования всех ресурсов в выделенные объекты. Подробнее об этом можно прочитать здесь.

Функции Fileinfo и объекты finfo

Такие функции, как finfo_file и finfo_open, ранее принимали и возвращали ресурсы. Начиная с PHP 8.1 они работают с объектами finfo.

Функции IMAP и объекты IMAPConnection

Как и в случае функций Fileinfo, функции IMAP, такие как imap_body и imap_open, больше не работают с ресурсами.


Запрещена передача null в не поддерживающие null аргументы внутренних функций rfc​

Суть изменения проста: внутренние функции в настоящее время принимают null в качестве аргументов, которые не могут иметь значение null, а данный RFC запрещает такое поведение. Например, сейчас возможен такой вызов:

str_contains("string", null);
В PHP 8.1 при вызовах такого рода будет выдаваться предупреждение об их упразднении (deprecation), а в PHP 9 эти предупреждения станут ошибками типизации.

Мелкие изменения​

С каждым выпуском в язык вносится множество небольших изменений. Все они перечислены в руководстве UPGRADING на GitHub — обязательно ознакомьтесь с ним, если хотите знать о таких мелочах.

Вот сводка наиболее существенных изменений:

  • MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH больше не работает.
  • MYSQLI_STORE_RESULT_COPY_DATA больше не работает.
  • PDO::ATTR_STRINGIFY_FETCHES теперь работает и с логическим типом данных (boolean).
  • При использовании эмулированных подготовленных операторов целые числа и числа с плавающей запятой в наборах результатов PDO MySQL и SQLite будут возвращаться с использованием собственных типов PHP вместо строк.
  • Такие функции, как htmlspecialchars и htmlentities, теперь будут по умолчанию преобразовывать символ ' в '; некорректные данные в кодировке UTF-8 также будут заменяться символом Юникода, а не пустой строкой.
  • В функции hash, hash_file и hash_init добавлен новый аргумент $options; по умолчанию он имеет значение [], так что это не повлияет на уже написанный код.
  • Добавлена поддержка MurmurHash3 и xxHash.
На этом пока все. Я собираюсь регулярно обновлять эту статью в течение года, поэтому оформите подписку, если хотите быть в курсе. Вы рады скорому выходу PHP 8.1? Поделитесь своими ожиданиями со мной в Twitter!

Источник статьи: https://habr.com/ru/company/otus/blog/567710/
 
Сверху