Ежегодный релиз PHP уже не за горами! PHP 8.6 выйдет 19 ноября 2026 года. Сейчас PHP 8.6 находится на стадии бета-тестирования: заморозка добавления новых возможностей (feature freeze) запланирована на 22 сентября, а первый релиз-кандидат выйдет двумя днями позже:

#График релизов

На странице подготовки PHP 8.6 опубликован следующий график выпуска:

  • С Alpha 1 по Alpha 3: с 2 июля по 30 июля 2026 года
  • Beta 1 (мягкая заморозка возможностей): 13 августа 2026 года
  • Beta 3: 10 сентября 2026 года
  • Заморозка возможностей (feature freeze): 22 сентября 2026 года
  • RC 1: 24 сентября 2026 года
  • RC 4: 5 ноября 2026 года
  • GA (финальный релиз): 19 ноября 2026 года

Релиз-менеджерами выступают Даниэль Шерцер, Маттео Беккати и Джо Фергюсон.

#Частичное применение функций

Частичное применение функций (partial function application, PFA) позволяет вызывать функцию с заранее переданной частью аргументов, получая взамен замыкание, которое принимает оставшиеся аргументы. Плейсхолдер  ?  указывает на одиночный аргумент, который будет передан позже, а  ...  заменяет все оставшиеся аргументы:

$makeSlug = str_replace(' ', '-', ?);
 
$makeSlug('Hello World'); // Hello-World
 
$titles = array_map(strtolower(?), $titles);
 

Полученное замыкание сохраняет имена параметров, типы и значения по умолчанию исходной функции. Передаваемые вами аргументы вычисляются в момент создания частичного применения, а не при его вызове. Последующий RFC определил, что каждый плейсхолдер  ?  становится обязательным параметром в замыкании, даже если исходный параметр был необязательным.

Более ранняя версия этого предложения была отклонена в 2021 году. Вторая версия RFC была принята единогласно (33 голоса против 0).

#Функция clamp()

Новая функция  clamp()  возвращает переданное значение, если оно находится в заданных границах, либо ближайшую границу, если значение выходит за их пределы:

clamp(10, min: 0, max: 100);  // 10
clamp(101, min: 0, max: 100); // 100
clamp(-1, min: 0, max: 100);  // 0
 

Она работает с любыми сравниваемыми типами, включая строки и объекты  DateTime . Если передать  $min  больше, чем  $max , будет выброшено исключение  ValueError . Эта функция заменяет распространенную конструкцию  min(max($value, $min), $max) , в которой легко запутаться.

#Класс Duration

В PHP 8.6 добавлен  Time\Duration  — финальный readonly-класс, представляющий временной интервал (в стиле секундомера) с наносекундной точностью. Он содержит фабричные методы для каждой единицы измерения, арифметические методы и поддержку сравнения:

use Time\Duration;
 
$oneSecond = Duration::fromSeconds(1);
$halfSecond = $oneSecond->divideBy(2);
$total = $oneSecond->add($halfSecond);
 
$delay = Duration::fromMilliseconds(100)->multiplyBy(2 ** $attempt);
 
$total > $delay; // comparison operators work
 

Интервалы также можно создавать из строки формата ISO 8601. Этот класс задуман как общий тип, который встроенные функции и новый API опроса (polling API) смогут принимать вместо нетипизированных целых чисел и чисел с плавающей точкой. Полный список методов смотрите в Duration RFC.

#Значения по умолчанию для readonly-свойств

Начиная с PHP 8.6, readonly-свойства могут иметь значения по умолчанию. До версии 8.6 это приводило к ошибке компиляции, из-за чего было неудобно реализовывать свойства интерфейсов «только для чтения» (появившиеся в PHP 8.4) с фиксированным значением:

final readonly class CreateBooksTable implements Migration
{
    public string $name = '2026_01_01_create_books_table';
}
 

Этот RFC лишь снимает ограничение. Семантика readonly остается прежней, поэтому свойство по-прежнему нельзя перезаписать после инициализации.

#Doc-комментарии для параметров функций

Doc-комментарии теперь можно размещать непосредственно перед параметром, а метод  ReflectionParameter::getDocComment()  позволяет их считывать. Это избавляет от необходимости дублировать имя параметра в теге  @param  над функцией:

function search(
    /** Terms to search for in the database */
    string $query,
    /** Maximum number of entries to return */
    int $limit = 10,
): array {
    // ...
}
 

Статические анализаторы и IDE могут читать комментарий прямо из самого параметра. См. RFC по Doc-комментариям параметров.

#API опроса (Polling API)

Новое пространство имен  Io\Poll  предоставляет PHP унифицированный интерфейс к системным механизмам опроса: epoll в Linux, kqueue во FreeBSD и macOS, event ports в Solaris и WSAPoll в Windows. Оно заменяет  stream_select()  для тех, кто разрабатывает циклы событий (event loops) или асинхронные среды выполнения в userland-коде:

use Io\Poll\{Context, Event, StreamPollHandle};
 
$poll = new Context();
$server = stream_socket_server('tcp://0.0.0.0:8080');
stream_set_blocking($server, false);
 
$poll->add(new StreamPollHandle($server), [Event::Read], ['type' => 'server']);
 
while (true) {
    foreach ($poll->wait(1) as $watcher) {
        if ($watcher->hasTriggered(Event::Read)) {
            // accept the connection
        }
    }
}
 

В RFC отмечается, что основная мотивация является внутренней (например, обработка сигналов и улучшения в FPM), а асинхронные фреймворки в пространстве пользователя рассматриваются как второстепенная аудитория. См. Polling API RFC.

#Enum SortDirection

В ядро встроен глобальный enum  SortDirection  с вариантами  Ascending  и  Descending . На данный момент в самом ядре его еще ничего не использует. RFC предлагает его в качестве общего типа, чтобы библиотеки перестали определять собственные аналоги (в качестве примера приводятся построители запросов):

$query->orderBy('created_at', SortDirection::Descending);
 

#Enums могут реализовывать __debugInfo()

Когда перечисления (enums) появились в PHP 8.1, им не разрешалось определять большинство магических методов. PHP 8.6 снимает это ограничение для  __debugInfo() , поскольку этот метод не требует состояния, что позволяет настраивать вывод  var_dump() :

enum Status: int
{
    case Ok = 200;
 
    public function __debugInfo(): array
    {
        return [__CLASS__ . '::' . $this->name . ' = ' . $this->value];
    }
}
 

#Обработка ошибок в потоках

Потоки (streams) получают унифицированную модель ошибок. Новая опция контекста  error_mode  позволяет выбирать между текущим поведением (предупреждения), исключениями или игнорированием ошибок, а функция  stream_last_errors()  возвращает структурированные объекты  StreamError  для последней операции:

$context = stream_context_create([
    'stream' => ['error_mode' => StreamErrorMode::Exception],
]);
 
try {
    $stream = fopen('/nonexistent/file.txt', 'r', false, $context);
} catch (StreamException $e) {
    foreach ($e->getErrors() as $error) {
        echo $error->code->name . ': ' . $error->message;
    }
}
 

RFC Stream Error Handling определяет более 50 семантических кодов ошибок в перечислении  StreamErrorCode .

#Развитие расширения URI

Расширение URI, появившееся в PHP 8.5, получило классы-строители (builders), благодаря чему теперь можно собирать URI без создания промежуточных объектов для каждого компонента:

$uri = new Uri\Rfc3986\UriBuilder()
    ->setScheme('https')
    ->setHost('example.com')
    ->setPath('/foo/bar')
    ->build();
 

Следующий RFC по развитию URI также добавляет методы  getUriType()  и  getHostType() , а также функции для процентного кодирования (percent-encoding) отдельных компонентов URI.

#Безопасные настройки сессий по умолчанию

Для новых установок меняются три значения по умолчанию в  php.ini  для сессий:

Настройка Старое значение Новое значение
 session.use_strict_mode   0   1 
 session.cookie_httponly   0   1 
 session.cookie_samesite  не задано  Lax 

Laravel самостоятельно управляет своими cookie-файлами сессий, поэтому большинство приложений это не затронет. Разработчикам приложений, использующих нативные сессии PHP и полагающихся на старые значения по умолчанию, стоит ознакомиться с RFC по настройкам сессий по умолчанию.

#Узнать больше