Версия PHP 8.1 находится в активной разработке и будет выпущена 25 ноября 2021 г. Следует иметь в виду, что эта дата может измениться, если основная команда разработчиков решит, например, добавить дополнительный бета-выпуск. Мы уже знаем о новых возможностях, повышении производительности, изменениях и упразднении сомнительной функциональности. Давайте рассмотрим эти новшества по порядку.
Добавление перечислений будет значительным улучшением PHP — я, например, с нетерпением жду их появления в PHP 8.1. Вот пример того, как они будут выглядеть:
enum Status {
case Pending;
case Active;
case Archived;
}
И вот как они будут использоваться:
Более подробно о том, как можно использовать перечисления, вы можете узнать из уже упомянутой статьи.
Вот простой пример использования файберов:
$fiber = new Fiber(function (): void {
$valueAfterResuming = Fiber::suspend('после приостановки');
// …
});
$valueAfterSuspending = $fiber->start();
$fiber->resume('после возобновления');
Если вы хотите узнать больше о файберах и о том, что они могут и чего не могут делать, прочтите эту статью.
Дмитрий сообщает, что в результате производительность повышается на 5–8 %, — одна из приятных мелочей, ожидаемых от PHP 8.1.
$array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump($array); // ["a" => 1, "b" => 2]
function dd(mixed $input): never
{
// dump
exit;
}
never отличается от void тем, что void позволяет программе продолжить выполнение. Этот тип может показаться необычным новшеством, но на деле он будет весьма полезен для статических анализаторов.
В 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
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
}
$file = fopen("sample.txt", "w");
fwrite($file, "Какое-то содержимое");
if (fsync($file)) {
echo "Файл успешно сохранен на диск.";
}
fclose($file);
Поскольку синхронизация c диском — это операция файловой системы, функция fsync будет работать только с обычными файловыми потоками. При попытке синхронизации нефайловых потоков будет выдаваться предупреждение.
016 === 0o16; // true
016 === 0O16; // true
$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, больше не работают с ресурсами.
str_contains("string", null);
В PHP 8.1 при вызовах такого рода будет выдаваться предупреждение об их упразднении (deprecation), а в PHP 9 эти предупреждения станут ошибками типизации.
Вот сводка наиболее существенных изменений:
Источник статьи: https://habr.com/ru/company/otus/blog/567710/
Новые возможности
Как и в каждом выпуске, в 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.
Источник статьи: https://habr.com/ru/company/otus/blog/567710/