PHP 8.5: Обзор ключевых нововведений и улучшений
20 ноября 2025 года состоялся релиз PHP 8.5 — значительного обновления популярного языка программирования. Этот релиз акцентирует внимание на повышении читаемости кода, упрощении отладки, усилении безопасности и удобстве работы с данными. Основные изменения направлены на то, чтобы сделать разработку более интуитивной и эффективной. Подробную информацию о релизе можно найти на официальном сайте PHP. Среди наиболее заметных новшеств:
Встроенное расширение URI для надежного парсинга URL
Оператор Pipe (|>) для цепочек вызовов
Улучшенная функция clone с поддержкой модификации свойств
Атрибут #[\NoDiscard] для контроля возвращаемых значений
Поддержка замыканий и вызовов первого класса в константных выражениях
Постоянные дескрипторы cURL Share
Новые функции array_first() и array_last()
Встроенное расширение URI: Надежный парсинг URL
Одним из главных улучшений стало появление встроенного расширения URI, которое дополняет устаревшую функцию
parse_url(). Теперь доступны два класса: \Uri\Rfc3986\Uri (соответствует стандарту RFC 3986) и
\Uri\WhatWg\Url (соответствует спецификации WHATWG, используемой в браузерах).
Эти классы обеспечивают более строгий и полный разбор URL, включая удобные методы для получения и изменения компонентов,
а также автоматическую нормализацию.
Пример с простой ссылкой:
$url = 'https://www.php.net/releases/8.5/ru.php';
$components = parse_url($url);
dump($components);
//array [
// "scheme" => "https"
// "host" => "www.php.net"
// "path" => "/releases/8.5/ru.php"
//]
$uri = new \Uri\Rfc3986\Uri($url);
dump($uri);
//Uri\Rfc3986\Uri {
// scheme: "https"
// username: null
// password: null
// host: "www.php.net"
// port: null
// path: "/releases/8.5/ru.php"
// query: null
// fragment: null
//}
$uri = new \Uri\WhatWg\Url($url);
dump($uri);
//Uri\WhatWg\Url {
// scheme: "https"
// username: null
// password: null
// host: "www.php.net"
// port: null
// path: "/releases/8.5/ru.php"
// query: null
// fragment: null
//}
Преимущества очевидны: вместо массива с возможными отсутствующими ключами мы получаем объект с четкими геттерами,
возвращающими null при отсутствии компонента.
Сложный URL с аутентификацией:
$url = 'https://root:pass@www.php.net/releases/8.5/ru.php?query=params';
$uri = new \Uri\Rfc3986\Uri($url);
echo $uri->getUsername(); // root
echo $uri->getPassword(); // pass
echo $uri->getQuery(); // query=params
Особенно полезен \Uri\WhatWg\Url для международных доменов (IDN):
$url = 'https://root:pass@домер.рф/releases/8.5/ru.php?query=params';
$uri = new \Uri\WhatWg\Url($url);
echo $uri->getUnicodeHost(); // домер.рф
echo $uri->getAsciiHost(); // xn--d1acuhm.xn--p1ai
Класс WHATWG автоматически конвертирует Punycode и лучше справляется с современными требованиями браузеров.
Оператор Pipe (|>) — Читаемые цепочки обработки
Долгожданный оператор |> позволяет передавать результат одного выражения как первый аргумент в следующее, делая код линейным и легким для чтения. Пример генерации slug:
$title = ' PHP 8.5 Released ';
$slug = $title
|> trim(...)
|> fn($str) => str_replace(' ', '-', $str)
|> fn($str) => str_replace('.', '', $str)
|> strtolower(...);
echo $slug; // php-85-released
Это значительно чище вложенных вызовов и упрощает понимание последовательности операций.
Clone With: Клонирование с немедленной модификацией
Теперь функция clone принимает второй аргумент — ассоциативный массив свойств для изменения в новой копии объекта.
readonly class Color
{
public function __construct(
public int $red,
public int $green,
public int $blue,
public int $alpha = 255,
) {}
public function withAlpha(int $alpha): self
{
return clone($this, ['alpha' => $alpha]);
}
}
$blue = new Color(79, 91, 147);
$transparentBlue = $blue->withAlpha(128);
Идеально для immutable-объектов и паттерна "withers".
Атрибут #[\NoDiscard]
Этот атрибут заставляет интерпретатор предупреждать, если возвращаемое значение функции игнорируется.
#[\NoDiscard]
function getPhpVersion(): string
{
return 'PHP 8.5';
}
getPhpVersion(); // Предупреждение: возвращаемое значение не используется
Полезно для функций, где игнорирование результата может быть ошибкой (например, API-вызовы).
Замыкания в константных выражениях
Теперь статические замыкания и вызовы первого класса разрешены в контекстах, где требуются константы: атрибуты, default-значения свойств/параметров. Пример с атрибутом:
final class PostsController
{
#[AccessControl(static fn(Request $request, Post $post): bool =>
$request->user === $post->getAuthor()
)]
public function update(Request $request, Post $post): Response
{
// ...
}
}
Упрощает конфигурацию без лишних классов.
Постоянные дескрипторы cURL Share
Новая функция curl_share_init_persistent() создает дескрипторы, сохраняющиеся между запросами, с автоматическим
переиспользованием.
$sh = curl_share_init_persistent([CURL_LOCK_DATA_DNS, CURL_LOCK_DATA_CONNECT]);
$ch = curl_init('https://php.net/');
curl_setopt($ch, CURLOPT_SHARE, $sh);
curl_exec($ch);
Снижает overhead на инициализацию в долгоживущих приложениях (FPM, Swoole).
Функции array_first() и array_last()
Простые, но удобные помощники:
$events = [...];
$lastEvent = array_last($events); // null если массив пуст
$firstEvent = array_first($events);
Возвращают null для пустого массива — идеально сочетается с ??.
Другие заметные улучшения
- Фатальные ошибки теперь включают полный стек вызовов (backtrace).
- Атрибуты разрешены на константах, трейтах и свойствах.
#[\Override]работает со свойствами.- Асимметричная видимость для статических свойств.
- Свойства в конструкторе могут быть
final. - Новый метод
Closure::getCurrent()для рекурсии в анонимных функциях. - Поддержка "
partitioned" в cookies. - Новые функции:
get_error_handler(),get_exception_handler(),grapheme_levenshtein(). - Улучшения в DOM:
getElementsByClassName(),insertAdjacentHTML().
Устаревшие возможности и breaking changes
- Удалена поддержка обратных кавычек как
shell_exec(). - Неканонические типы (
boolean,integer) больше не разрешены. - Удалена INI-настройка disable_classes.
- Другие мелкие deprecation'ы (см. migration guide).
PHP 8.5 — это шаг вперед в удобстве и современности языка. Рекомендуется обновляться, особенно если вы цените чистый и выразительный код. Тестируйте на staging-окружении, чтобы избежать сюрпризов с deprecation'ами!