PHP 8.5: Главные нововведения
PHP 8.5 продолжает курс «выразить больше в самом языке»: оператор конвейера (|>), #[\NoDiscard], чтобы не игнорировать возвращаемые значения, и замыкания в константных выражениях для атрибутов и значений по умолчанию. На уровне платформы — всегда включённое URI-расширение, строгий режим filter и серьёзные изменения PDO / Opcache: закладывайте время на QA не только под новый синтаксис, но и под расширения и сборку/INI.
Содержание (Оглавление)
- Оператор конвейера (
|>) - Замыкания и first-class callable в константных выражениях
#[\NoDiscard]и приведение(void)- Расширение URI (RFC 3986 / WHATWG URL)
- Заметные обновления библиотек и расширений
- Новые функции (
array_first,array_last, обработчики ошибок, …) - Практические рецепты
- Обратно несовместимые изменения (миграционные заметки)
- Deprecated (чеклист верхнего уровня)
- Прочие изменения и эксплуатация (Opcache, INI, производительность)
Оператор конвейера (|>)
Оператор pipe передаёт значение слева в одноаргументный callable справа. Удобен для цепочек преобразований без временных переменных.
$result = 'Hello World' |> strlen(...);
// То же: $result = strlen('Hello World');
Ограничения: справа — callable ровно с одним параметром (не by-ref). Стрелочные функции в связке с |> нужно заключать в скобки. Подробности — в руководстве по functional operators.
Замыкания и first-class callable в константных выражениях
В PHP 8.5 замыкания и first-class callable разрешены в константных выражениях, в том числе:
- аргументы атрибутов;
- значения по умолчанию у свойств и параметров;
- константы и константы класса.
Это расширяет выразительность там, где недостаточно скаляра на этапе компиляции/линковки.
#[\NoDiscard] и приведение (void)
#[\NoDiscard] помечает функции/методы, у которых возвращаемое значение нежелательно игнорировать (по духу близко к [[nodiscard]] в C++).
(void) явно говорит: «значение я отбрасываю намеренно». Само по себе выполнение не меняет, но может подавлять предупреждения, связанные с #[\NoDiscard], и помогает статическому анализу.
#[\NoDiscard]
function loadConfig(): array { return []; }
(void) loadConfig(); // намеренный discard
Расширение URI (RFC 3986 / WHATWG URL)
В PHP 8.5 добавлено всегда включённое расширение uri для разбора и работы с URI/URL по RFC 3986 и модели WHATWG URL. Имеет смысл там, где важна спецификация, а не ручной substr по пользовательскому вводу.
Заметные обновления библиотек и расширений
- Filter: флаг
FILTER_THROW_ON_FAILURE— при ошибке валидации можно получить исключение вместоfalse(нельзя совмещать сFILTER_NULL_ON_FAILURE). - Intl: например
IntlListFormatter,Locale::addLikelySubtags()/minimizeSubtags(), дополнительные константы стилей NumberFormatter для валют (зависят от версии ICU). - Session / cookies:
session_set_cookie_params(),session_get_cookie_params(),session_start(), а такжеsetcookie()/setrawcookie()— поддержка partitioned cookies через ключ"partitioned". - Standard:
mail()при sendmail возвращает реальные ошибки и предупреждает при аварийном завершении sendmail;getimagesize()— HEIF/HEIC, SVG (при libxml), дополнительные поля единиц измерения размеров. - DOM: например
Dom\Element::$outerHTML, свойство$childrenу реализацийDom\ParentNode. - cURL: новые ключи/опции
curl_getinfoиcurl_setopt(прокси, аутентификация, большие размеры, режимы follow location, TLS и т.д. — часто зависят от версии libcurl).
Новые функции (array_first, array_last, обработчики ошибок, …)
Кратко:
- Core:
get_error_handler(),get_exception_handler(),Closure::getCurrent() - Standard:
array_first(),array_last() - Reflection: доработки
ReflectionConstant,ReflectionProperty::getMangledName() - Opcache:
opcache_is_script_cached_in_file_cache() - PostgreSQL / SQLite / DOM и др. — см. new functions
Практические рецепты
Конвейер нормализации
$slug = $raw
|> trim(...)
|> strtolower(...)
|> preg_replace('/\s+/', '-', ...);
Filter с исключениями вместо false
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, FILTER_THROW_ON_FAILURE);
Первый и последний элемент без ручного индекса
$first = array_first($list);
$last = array_last($list);
Обратно несовместимые изменения (миграционные заметки)
Ядро языка / runtime
class_alias(): нельзя использовать"array"и"callable"как имена алиаса.- Нестрогое сравнение с bool для «несравнимых» объектов (enum,
CurlHandle, …): поведение унифицировано с(bool)$object. gc_collect_cycles(): возвращаемое значение больше не учитывает строки/ресурсы, косвенно собранные через циклы.- Final-подклассы: где раньше ограничивали подстановку
static, допускаютсяselfили имя конкретного класса. - Tick handlers: выполняются после shutdown-функций, деструкторов и очистки output handlers.
- Трейты: изменён порядок привязки относительно родителя (тонкий момент — перепроверьте трейт-тяжёлый код).
- Ошибки компиляции/линковки классов: изменён порядок обработки; исключения из user error handler могут вести себя иначе.
#[\Attribute]на abstract class, enum, interface или trait: ошибка на этапе компиляции, если не отложена валидация через#[\DelayedTargetValidation](см. мануал).- INI
disable_classes: удалена. - Деструктуризация не-массива и не-
nullчерез[]/list(): предупреждение. - Приведение к int для вне диапазона float / числовых строк и NAN: предупреждения.
Opcache
- Opcache всегда встроен в бинарник PHP и загружен; строка
zend_extension=opcache.so/.dllдаёт предупреждение. Сборка sharedopcache.soи флаги configure для отдельного модуля убраны — обновите документацию и образы.
PDO (высокий риск)
- Числовые значения
PDO::FETCH_*для ряда флагов изменились — перепроверьте конфиги/БД, где хранятся режимы выборки числом. - Аргументы конструктора при
PDO::FETCH_CLASS: семантика как уcall_user_func_array(строковые ключи как именованные аргументы; изменены правила по ref). - Ограничения на сочетание
FETCH_PROPS_LATE,FETCH_INTOсfetchAll()и т.д. — см. migration85 incompatible.
DOM / SPL / прочее
- Клонирование живых
NodeList/NamedNodeMap(классический DOM иDom\*) теперь падает (раньше давало нерабочий объект). ArrayObject: не принимает enum как элементы.- mysqli: повторный вызов конструктора на уже созданном объекте — Error.
- Многие расширения вместо
TypeErrorили тихого поведения бросаютValueError(FileInfo и nul bytes, LDAP, сокеты, SNMP и т.д.).
Deprecated (чеклист верхнего уровня)
В 8.5 затронуты не только «мелочи»: старые имена приведений (integer) и т.п., обратные кавычки как shell_exec, мягкий отказ от __sleep/__wakeup в пользу __serialize/__unserialize, поверхность PDO (схема uri: в DSN, драйверные константы/методы на базовом PDO), curl_close / share close, finfo_close, imagedestroy, xml_parser_free и многое другое. Источник истины — официальный список migration85 deprecated; планируйте рефакторинг до перехода на жёсткие ошибки в следующих минорных версиях.
Прочие изменения и эксплуатация (Opcache, INI, производительность)
- CLI:
--ini=diffпоказывает отличия INI от встроенных дефолтов;cli_set_process_title()падает, если заголовок слишком длинный (без тихого обрезания). - Core INI: например
fatal_error_backtraces,max_memory_limit, ограничения на ростmemory_limitв runtime. - Opcache INI: например
opcache.file_cache_read_onlyдля read-only кэша; настройка JIT hot loop; корректный отчёт при сменеopcache.memory_consumption. - Производительность: быстрее создание исключений, ускорение колбэков по массивам,
urlencode, Reflection, SIMD на ARM, опциональный TAILCALL VM при Clang ≥ 19 и др. — см. other changes.
Итог
PHP 8.5 сочетает удобный синтаксис (pipes, константные замыкания, семантика discard) и ужесточение платформы (PDO, Opcache, валидация в расширениях). План апгрейда: внедрить синтаксис там, где он проясняет намерение, затем прогнать интеграционные тесты по режимам PDO, cookie/session, коду, завязанному на устаревшие close-хелперы и на старое нестрогое сравнение объектов с bool.