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

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

что обещает нам новый выпуск

PHP 8.1 в настоящее время находится в активной разработке и, вероятно, будет выпущен где-то в конце ноября 2021 года

Но мы уже знаем некоторые функции, изменения и устаревшие версии, поэтому давайте рассмотрим их уже сейчас. Имейте в виду, что этот список как и PHP 8 будет расти с годами.

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

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

Распаковка массива с помощью строковых ключей rfc

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


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

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

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

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

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

Возможно, время от времени, вам приходится иметь с этим дело: определять, находятся ли ключи массива в числовом порядке, начиная с индекса 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;
}

 

Явное восьмеричное целочисленное буквальное обозначение rfc

Теперь вы можете использовать 0o (нуль и маленькая буква o) и 0O (нуль и большая буква O) для обозначения восьмеричных чисел. Предыдущее обозначение с префиксом числа "0" по-прежнему работает:


016 === 0o16; // true
016 === 0O16; // true

Enums (Перечисления) rfc

Этот RFC все еще обсуждается.

Несмотря на то, что голосования еще не было, это предложение о добавлении перечислений было встречено с большим энтузиазмом.

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


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);

Критические изменения

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

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

Небольшое изменение способа использования $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. Помните, что большинство из нас выиграет от этого изменения, учитывая положительное влияние на производительность, которое оно оказывает во всем нашем коде. 

Устарела передача null не null-ых аргументов внутренним функциям rfc

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


str_contains("string", null);

 В PHP 8.1 такие ошибки будут вызывать предупреждение об устаревании, в PHP 9 они будут преобразованы в ошибки типа.



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


Сергей Мухин

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

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

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

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