PHP 7.3: Что нового? Когда релиз?

Опубликовано 1 неделю назад 0 комментариев 202 просмотра

Эта запись дополняется в live-режиме и будет дополняться до тех пор, пока не состоится публичный релиз PHP 7.3. Идею подглядел у Ayesh Karunaratne, оттуда же взяты и с заботой переведены первые несколько нововведений.

По плану до конца лета 2018 года будет определен полный список новшеств, которые войдут в новую версию PHP 7.3. С учетом цикла 1 год - 1 крупное обновление, которого придерживаются разработчики PHP начиная с версии 7.0, релиз PHP 7.3 ожидается в ноябре-декабре 2018 года.

Изменение требований к Heredoc и Nowdoc

Синтаксис Heredoc и Nowdoc, который помогал при использовании многострочных строк, имел жесткое требование - в строке, содержащей идентификатор недопустимо было использование каких-либо еще символов (кроме ;).

Например:

$foo = <<<IDENTIFIER
the crazy dog jumps over the lazy fox
"foo" bar;
IDENTIFIER

В строке с последним IDENTIFIER не могло находиться ничего, кроме IDENTIFIER - как до, так и после идентификатора (кроме исключения).

RFC для PHP 7.3 убирает это ограничение с целью сделать код более читаемым. При этом пришлось сломать отступы, используемые в остальной части кода, так что в here/now теперь могут использоваться токены.

RFC вносит изменения в синтаксис Heredoc/Nowdoc:

  1. Строка с закрывающим токеном может начинаться с отступов (пробелы и табы).
  2. Пробелы и табы не должны смешиваться. Иначе будет вызвана ошибка Parse error: Invalid indentation - tabs and spaces cannot be mixed in .. on line ...
  3. Отступы, находящиеся в закрывающей строке перед идентификатором будут удалены из получаемой переменной.
  4. Если число символов отступов, используемых в конце токена превышает число символов отступов в выражении, вы получите Parse error: Invalid body indentation level (expecting an indentation level of at least ..) in .. on line ...
  5. После закрывающего токена можно использовать другие выражения PHP.

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

$foo = ['foo', 'bar', <<<EOT
  baz
    -  hello world! --
  ahoy
  EOT, 'qux', 'quux'
];

var_dump($foo);
array(5) {         
  [0]=>            
  string(3) "foo"  
  [1]=>            
  string(3) "bar"  
  [2]=>            
  string(29) "baz  
  -  hello world! --
ahoy"
  [3]=>
  string(3) "qux"
  [4]=>
  string(4) "quux"
}

Обратите внимание как пробелы, введеные в закрывающей строке перед токеном не попали в финальный вывод var_dump(), а после закрытия токена EOT мы продолжили добавлять элементы в массив.

Обратная совместимость

$foo = <<<HELLO
  HELLO_WORLD <-- не вызовет завершение строки
  HELLOWORLD <-- тоже не вызовет
  HELLO WORLD <-- строка завершится
HELLO;

Новая версия PHP предполагает завершение на 4 строке вместо 5, как было в более ранних версиях.

Разрешение запятой в вызовах функций и методов

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

foo('bar', 'baz',); // Обратите внимание на конечную запятую после 'baz'

В ранних версиях PHP будет вызвана ошибка Parse error: syntax error, unexpected ')' in .. on line ...

Вы не можете использовать несколько запятых в конце, равно как и использовать запятые для пропуска аргументов. Некорректным остается использование запятых в объявлении функций/методов.

function foo($bar, $baz, ) // по прежнему запрещено
{
}

Лично я так и не смог понять/грамотно перевести причину, по которой вообще ввели такой синтаксис. Единственное предположение - объявление массива вида ['foo' => 'bar',] не вызывает никаких ошибок, и данное нововведение имеет чисто визуальную необходимость..

Возможность вызвать исключение при работе с json_encode() и json_decode()

Все время существования json_encode() и json_decode() вместо ошибки в случае возникновения таковой возвращали false. Нововведение добавляет возможность указать JSON_THROW_ON_ERROR 4 аргументом для вызова ошибки:

try {
  json_decode("{", false, 512, JSON_THROW_ON_ERROR);
}
catch (\JsonException $exception) {
  echo $exception->getMessage();
}

Новый \JsonException является подклассом \Exception и, как и константа JSON_THROW_ON_ERROR, объявляются в глобальном пространстве имен.

На данный момент имеются библиотеки вроде daverandom/exceptional-json, добавляющие аналогичный функционал в PHP 7.2. С релизом PHP 7.3 вы можете избавиться от лишних пакетов и вызовов json_last_error() каждый раз после выполнения операции.

Обратная соместимость

Если вы объявили свое собственное исключение и/или константу с аналогичными именами - пришло время их изменить.

Ссылки в list()

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

$arr = ['apple', 'orange'];
list($a, &$b) = $arr;
$b = 'banana';
echo $arr[1];
// Fatal error: [] and list() assignments cannot be by reference in .. on line ..

В PHP 7.3 echo $arr[1] будет выводить banana. Синтаксис [$a, &$b] = $arr также получит это нововведение.

Добавлена функция is_countable()

PHP 7.2 вызывал предупреждение при вызове count() с не-счетным (countable) аргументом. По сути, is_countable() является логичной альтернативой $foo instanseof \Countable, которую почему-то забыли добавить в PHP 7.2. До официального релиза можно воспользоваться моим вариантом:

function is_countable($arg)
{
    return is_array($arg) || $arg instanceof \Countable;
}

Объявлена устаревшей функция image2wbmp()

Функция image2wbmp(), начиная с PHP 5.x являющейся фактически идентичной imagewbmp(), объявлена устаревшей как бессмысленный дубль второй и будет удалена в следующей версии (предоположительно, PHP 8.x).

В ответ на сообщение

Нажимая на кнопку «Отправить» вы даете свое согласие на обработку персональных данных в соответствии с законом №152-ФЗ «О персональных данных» от 27.07.2006 и принимаете условия Политики конфеденциальности.