PHP 8.5: Новые сообщения об ошибках

Разбираем новые сообщения об ошибках в PHP 8.5: pipe-оператор, deprecated поведение, проблемы с массивами, типами и глобальными константами. Как исправить ошибки и подготовить проект к миграции.

Введение

PHP 8.5 продолжает улучшать диагностику ошибок. Новые формулировки сообщений помогают разработчикам быстрее находить причины сбоев.

Изменения затронули несколько областей: проверку типов аргументов, контроль возвращаемых значений, работу со свойствами объектов. Все уточнения призваны устранить двусмысленность старых сообщений.

Далее рассмотрены ключевые нововведения, примеры ошибок и рекомендации по адаптации.

Ошибка syntax error, unexpected token ">" — несовместимость pipe-оператора

Ошибка возникает при использовании оператора |> в версиях PHP ниже 8.5. При переходе с PHP 8.5 на более старые версии этот синтаксис становится невалидным.

Пример кода, вызывающего ошибку:

echo "Hello World" |> mb_strtolower(...);

Оператор |> поддерживается только в PHP 8.5 и выше. Для обратной совместимости либо откажитесь от его использования, либо реализуйте условное выполнение кода.

Ошибка Arrow functions on the right hand side of |> must be parenthesized — требование скобок для стрелочных функций

Pipe-оператор |> поддерживает различные вызываемые объекты, но стрелочные функции требуют обязательного заключения в скобки. Это ограничение связано с особенностями парсера PHP.

Пример допустимого использования с различными вызываемыми объектами:

$result = "Hello World"
|> 'foo'
|> mb_strtolower(...)
|> function(string $x): string {return strtolower($x);}
|> new aClass()
|> [AnotherClass::class, 'aMethod'];

Ошибка возникает при попытке использовать стрелочную функцию без скобок:

// Ошибка:
|> fn($x) => trim($x);

// Корректно:
|> (fn($x) => trim($x));

При рефакторинге существующего кода под PHP 8.5 необходимо проверять использование стрелочных функций в цепочках |> и при необходимости добавлять скобки.

Предупреждение Using null as an array offset is deprecated — устаревшее использование null в индексах массива

Начиная с PHP 8.5 использование null в качестве индекса массива вызывает предупреждение об устаревании. Ранее null автоматически преобразовывался в пустую строку, что могло приводить к неявному поведению.

Пример проблемного кода:

$array = [1 => 'b'];
$array[null] = 3;

var_dump($array['']); // Выведет 3

Для сохранения логики явно преобразуйте null в пустую строку:

// Было:
$array[null] = $value;

// Стало:
$array[$key ?? ''] = $value;

Пересмотрите логику работы с массивами, где возможны null-ключи, и определите, является ли пустая строка корректной заменой или требуется обработка ошибок.

Предупреждение Non-canonical cast (integer) is deprecated — устаревшие варианты приведения типов

PHP 8.5 помечает как устаревшие неканонические варианты приведения типов. Для каждой операции теперь рекомендуется использовать краткую форму.

Устаревшие и рекомендуемые варианты:

Устаревший вариантРекомендуемый вариант
(integer)(int)
(boolean)(bool)
(double)(float)
(binary)(string)

Пример устаревшего кода:

$value = (integer) '123';

Исправленная версия:

$value = (int) '123';

Изменение затрагивает только синтаксис приведения типов и не влияет на семантику операций. Для автоматического исправления можно использовать инструменты статического анализа или регулярные выражения.

Подробнее об этом изменении читайте в статье: PHP 8.5: Отказ от устаревших приведений типов.

Предупреждение $http_response_header variable is deprecated — новая функция для HTTP-заголовков

Начиная с PHP 8.5, автоматическая переменная $http_response_header считается устаревшей. Эта переменная появлялась при выполнении сетевых запросов через функции вроде file_get_contents() или fopen() и содержала полученные HTTP-заголовки.

Пример устаревшего кода:

$content = file_get_contents('https://example.com');
if ($http_response_header) {
var_dump($http_response_header);
}

Вместо переменной следует использовать новую функцию http_get_last_response_headers(), доступную с PHP 8.4:

$content = file_get_contents('https://example.com');
$headers = http_get_last_response_headers();
if ($headers) {
var_dump($headers);
}

Функция возвращает массив заголовков аналогично старой переменной, но предоставляет более явный и предсказуемый интерфейс. Это изменение подготавливает код к будущей версии PHP 9, где переменная будет полностью удалена.

Ошибка syntax error, unexpected token "const" — проблема атрибутов в глобальных константах

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

Пример кода, вызывающего ошибку:

#[ExampleAttribute]
const APP_NAME = 'My Application';

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

Решение: Для обеспечения обратной совместимости можно использовать условное определение:

if (PHP_VERSION_ID >= 80500) {
#[ExampleAttribute]
const APP_NAME = 'My Application';
} else {
const APP_NAME = 'My Application';
}

Альтернативно, можно перенести константу в класс, где атрибуты поддерживаются с PHP 8.0:

class Config {
#[ExampleAttribute]
public const APP_NAME = 'My Application';
}

Часто задаваемые вопросы

Как исправить ошибку syntax error, unexpected token ">" в PHP 8.5?

Ошибка возникает при использовании pipe-оператора |> в версиях PHP ниже 8.5. Для исправления необходимо либо удалить pipe-оператор из кода, либо обеспечить выполнение этого кода только в PHP 8.5 и выше.

Почему стрелочные функции требуют скобок при использовании с pipe-оператором?

Это ограничение парсера PHP. Стрелочные функции должны быть заключены в скобки при использовании справа от оператора |>, например: |> (fn($x) => trim($x)). Другие типы вызываемых объектов такого ограничения не имеют.

Чем заменить использование null в качестве индекса массива?

Вместо $array[null] используйте явное преобразование: $array[$key ?? ''] = $value. Это устранит предупреждение и сохранит прежнюю логику. Также рекомендуется пересмотреть логику работы с массивами, где возможны null-ключи.

Какие варианты приведения типов стали устаревшими в PHP 8.5?

Устарели неканонические формы: (integer), (boolean), (double), (binary). Используйте краткие формы: (int), (bool), (float), (string). Изменение затрагивает только синтаксис, семантика операций остаётся прежней.

Какую функцию использовать вместо $http_response_header?

Начиная с PHP 8.4 доступна функция http_get_last_response_headers(), которая возвращает массив HTTP-заголовков последнего сетевого запроса. Эта функция заменит устаревшую переменную $http_response_header в будущих версиях PHP.

Можно ли использовать атрибуты для глобальных констант?

Да, в PHP 8.5 добавлена поддержка атрибутов для глобальных констант. Однако для обратной совместимости с более старыми версиями PHP рекомендуется либо использовать условное определение, либо переносить константы в классы.

Какие инструменты помогут подготовить проект к PHP 8.5?

Заключение

PHP 8.5 продолжает курс на улучшение диагностики ошибок и устранение неявного поведения. Рассмотренные изменения направлены на повышение ясности кода и подготовку к будущим версиям PHP.

Основные направления изменений:

Переход на PHP 8.5 требует внимания к деталям, но предлагает взамен более чистый и предсказуемый код. Большинство изменений имеет простые и понятные пути миграции, что упрощает процесс обновления.

Комментарии


Дополнительные материалы

Предыдущая Статья

Руководство по установке и обновлению PHP 8.5 для Debian и Ubuntu

Следующая Статья

Цикл релизов PHP: новые сроки поддержки 8.1-8.5 и EOL