PHP 8.1 в настоящее время находится в активной разработке и, вероятно, будет выпущен где-то в конце ноября 2021 года. Но мы уже знаем некоторые функции, изменения и устаревшие версии, поэтому давайте рассмотрим их уже сейчас. Имейте в виду, что этот список как и PHP 8 будет расти с годами. (1)
Новые возможности
Как и другие выпуски PHP, PHP 8.1 добавит несколько приятных новых возможностей. Также звучим некоторые функции, которые еще не были реализованы, но у которых есть хорошие шансы появиться в конечном релизе PHP. (1)
Распаковка массива с помощью строковых ключей
Распаковка массива уже была разрешена в PHP 7.4, но работала только с числовыми ключами. Причина, по которой строковые ключи не поддерживались раньше, заключается в том, что не было единого мнения о том, как объединять дубликаты массивов. RFC четко решает эту проблему, следуя семантике array_merge:
$array = ["a" => 1]; $array2 = ["b" => 2]; $arrayMerge = ["a" => 0, ...$array, ...$array2]; var_dump($arrayMerge); // ["a" => 1, "b" => 2]
Новый тип возврата never
Тип never может быть использован для того, чтобы указать, что функция фактически остановит поток приложения. Это можно сделать, выбросив исключение, вызывая exit/die или используя другие подобные функции.
function redirect(string $url): never { header('Location: ' . $url); exit(); } redirect('Test'); // код гарантирует не продолжение. do_something_else();
Тип возвращаемого значения never аналогичен существующему типу возвращаемого значения void, но тип never гарантирует, что программа завершится или выдаст исключение. Другими словами, объявленная функция/метод never типом вообще не должна вызывать return.
function foo(): never { return; } foo(); TypeError: dispatch(): Nothing was expected to be returned
Как видите, если функция/метод с типом never никак не сгенерирует исключение, или прекратит работу, то PHP выдаст исключение TypeError.
А если при never типе вызвать return, то PHP выдаст Fatal Error. Узнать об этом можно будет только во время вызова, а не во время синтаксического анализа.
function foo(): never { return; } foo();
Fatal error: A never function must not return in … on line 2
Исходный RFC предлагал использовать noreturn для этой цели. Впрочем последующее голосование в RFC прошло уже в пользу never и он был избран.
Новая функция array_is_list
Возможно, время от времени, вам приходится иметь с этим дело: определять, находятся ли ключи массива в числовом порядке, начиная с индекса 0. Точно так же, как 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
Любой массив с ключами, не начинающимися с нуля, или любой массив, в котором не все ключи являются целыми числами в последовательном порядке, результат будет false:
// ключи начинаются не с 0 array_is_list([1 => 'apple', 'orange']); // false // Ключи не отсортированы array_is_list([1 => 'apple', 0 => 'orange']); // false // Не все числовые ключи array_is_list([0 => 'apple', 'foo' => 'bar']); false // Непоследовательные ключи array_is_list([0 => 'apple', 2 => 'bar']); false
array_is_list принимает только параметры типа array. Передача любого другого типа вызовет исключение TypeError.
array_is_list не принимает iterable или другие объекты класса, подобные массиву, такие как ArrayAccess, SPLFixedArray и т.д.
array_is_list объявлен в глобальном пространстве имен.
Полифил функции будет выглядеть, как:
function array_is_list(array $array): bool { if (empty($array)) { return true; } $current_key = 0; foreach ($array as $key => $noop) { if ($key !== $current_key) { return false; } ++$current_key; } return true; }
Явное восьмеричное целочисленное буквальное обозначение
Теперь вы можете использовать 0o (нуль и маленькая буква o) и 0O (нуль и большая буква O) для обозначения восьмеричных чисел. Предыдущее обозначение с префиксом числа «0» по-прежнему работает:
016 === 0o16; // true
016 === 0O16; // true
Enums (Перечисления)
Перечисления будут добавлены в PHP 8.1.
Добавление перечислений было бы значительным улучшением в PHP.
Чтобы вы могли быстро увидеть, как они будут выглядеть, вот пример кода:
enum Status { case Pending; case Active; case Archived; } // И вот как они будут использоваться: class Order { public function __construct( private Status $status = Status::Pending; ) {} public function setStatus(Status $status): void { // … } } $order->setStatus(Status::Active);
Fibers
Файберы — также известные как «зеленые потоки» — это низкоуровневый механизм управления параллелизмом. Вероятно, вы не будете использовать их непосредственно в своих приложениях, но такие фреймворки, как Amphp и ReactPHP, будут широко их использовать.
Вот простой пример использования файберов:
$fiber = new Fiber(function (): void { $valueAfterResuming = Fiber::suspend('after suspending'); // … }); $valueAfterSuspending = $fiber->start(); $fiber->resume('after resuming');
Улучшения производительности
Дмитрий Стогов добавил некоторые улучшения в opcache, он называет это «кешем наследования».
Эта функция позволяет кэшировать ссылки между классами, так же как связанные классы могут быть предварительно загружены в PHP 7.4.
Дмитрий сообщает о приросте производительности от 5% до 8% благодаря этому изменению, приятная небольшая деталь, на которую следует обратить внимание в PHP 8.1.
Критические изменения
Хотя PHP 8.1 является последующей версией после PHP 8, все же будут внесены некоторые изменения, которые технически могут быть критическими, а также устаревшими. Давайте обсудим их по очереди.
Ограничить использование $GLOBALS
Небольшое изменение способа использования $GLOBALS существенно повлияет на производительность всех операций с массивами. Никита Попов отлично справляется с объяснением проблемы и решения в RFC . Это изменение означает, что в некоторых крайних случаях работать с $GLOBAL больше нельзя.
«То, что больше не поддерживается, — это запись в $GLOBALS, взятую как единое целое».
Все нижеперечисленное вызовет ошибку времени компиляции:
$GLOBALS = []; $GLOBALS += []; $GLOBALS =& $x; $x =& $GLOBALS; unset($GLOBALS);
Кроме того, передача $GLOBALS по ссылке вызовет ошибку времени выполнения:
by_ref($GLOBALS); // Run-time error
Никита проанализировал 2000 лучших пакетов на сайте packagist и нашел только 23 случая, на которые повлияет это изменение. Можно сделать вывод, что влияние этого технически критического изменения будет незначительным, поэтому internals решили добавить его в PHP 8.1. Помните, что большинство из нас выиграет от этого изменения, учитывая положительное влияние на производительность, которое оно оказывает во всем нашем коде.
Перенос Ресурсов в объекты
Эти изменения являются частью долгосрочного видения преобразования всех ресурсов в выделенные объекты. Вы можете прочитать об этом здесь.
Fileinfo функции с объектами finfo. Функции вроде finfo_file и finfo_open используются для приема и возврата ресурсов. Начиная с PHP 8.1, они работают с объектами finfo.
Функции IMAP с объектами IMAPConnection. Как и при изменении информации о файле, IMAP работает как imap_body, а imap_open больше не работает с ресурсами.
Устарела передача null не null-ых аргументов внутренним функциям
Это изменение простое: внутренние функции в настоящее время принимают null аргументы, которые не допускают значения NULL, этот RFC не рекомендует такое поведение. Например, сейчас это возможно:
str_contains("string", null);
В PHP 8.1 такие ошибки будут вызывать предупреждение об устаревании, в PHP 9 они будут преобразованы в ошибки типа.
Другие небольшие изменения
Вот краткое изложение наиболее значительных изменений:
-
MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH больше не действует
-
MYSQLI_STORE_RESULT_COPY_DATA больше не действует
-
PDO::ATTR_STRINGIFY_FETCHES теперь также работает с логическими значениями
-
Целые числа и числа с плавающей запятой в наборах результатов PDO MySQL и Sqlite будут возвращаться с использованием собственных типов PHP вместо строк при использовании эмулированных подготовленных операторов.
-
Такие функции, как htmlspecialchars и htmlentities по умолчанию, также переходят ‘в ‘; неверно сформированный UTF-8 также будет заменен символом Юникода вместо того, чтобы приводить к пустой строке
-
У hash, hash_file и hash_init есть дополнительный аргумент $options, по умолчанию он имеет значение [], поэтому не повлияет на ваш код.
-
Новая поддержка для MurmurHash3 и xxHash
Источники:
(1) Блог Сергея Мухина: https://sergeymukhin.com/blog/chto-novogo-v-php-81
Нет Ответов