Щорічний реліз PHP вже не за горами! PHP 8.6 буде випущено 19 листопада 2026 року. Зараз версія знаходиться у стадії бета-тестування, заморожування функціоналу відбудеться 22 вересня, а перший release candidate вийде через два дні.
Графік релізу
Сторінка підготовки PHP 8.6 містить наступний розклад:
- Alpha 1 - Alpha 3: 2 липня - 30 липня 2026
- Beta 1 (м'яке заморожування функціоналу): 13 серпня 2026
- Beta 3: 10 вересня 2026
- Заморожування функціоналу: 22 вересня 2026
- RC 1: 24 вересня 2026
- RC 4: 5 листопада 2026
- GA: 19 листопада 2026
Менеджерами релізу є Daniel Scherzer, Matteo Beccati та Joe Ferguson.
Часткове застосування функцій
Часткове застосування функцій (Partial Function Application, PFA) дозволяє викликати функцію з частково заповненими аргументами та отримувати closure, яке приймає решту параметрів. Плейсхолдер ? позначає один аргумент для заповнення пізніше, а ... замінює всі решту аргументів:
$makeSlug = str_replace(' ', '-', ?);
$makeSlug('Hello World'); // Hello-World
$titles = array_map(strtolower(?), $titles);
Отриманий closure зберігає імена параметрів, типи та значення за замовчуванням оригінальної функції. Аргументи, які ви надаєте, обчислюються під час створення часткового застосування, а не під час його виклику. Наступний RFC уточнив, що кожен плейсхолдер ? стає обов'язковим параметром closure, навіть якщо оригінальний параметр був опціональним.
Попередня версія цієї пропозиції була відхилена у 2021 році. RFC версії 2 пройшов з результатом 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; // оператори порівняння працюють
Об'єкти Duration також можна створювати з рядка тривалості у форматі ISO 8601. Клас призначений як спільний тип, який можуть приймати основні функції та новий polling API замість окремих цілих чисел та чисел з плаваючою комою.
Значення за замовчуванням для readonly-властивостей
Починаючи з PHP 8.6, readonly-властивості можуть мати значення за замовчуванням. До версії 8.6 це викликало помилку на етапі компіляції, що ускладнювало задоволення вимог get-only властивостей інтерфейсу з PHP 8.4 фіксованим значенням:
final readonly class CreateBooksTable implements Migration
{
public string $name = '2026_01_01_create_books_table';
}
RFC лише знімає обмеження. Семантика readonly залишається незмінною, тому властивість все ще не можна перепризначити після ініціалізації.
DocComments для параметрів функцій
Тепер 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 можуть читати коментар безпосередньо з параметра.
API для Polling
Новий простір імен Io\Poll надає PHP уніфікований інтерфейс до механізмів платформного polling: epoll на Linux, kqueue на BSD та macOS, event ports на Solaris та WSAPoll на Windows. Він замінює stream_select() для тих, хто створює event loops або асинхронні runtime у 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, а асинхронні фреймворки userland є другорядною аудиторією.
Enum SortDirection
Тепер вбудовано глобальний enum SortDirection з варіантами Ascending та Descending. Поки що жодна функція ядра його не приймає. RFC пропонує його як спільний тип, щоб бібліотеки перестали визначати власні, наприклад у query builder:
$query->orderBy('created_at', SortDirection::Descending);
Enum можуть реалізувати __debugInfo()
Коли enum з'явилися у версії 8.1, їм не дозволялося визначати більшість магічних методів. PHP 8.6 знімає це обмеження для __debugInfo(), оскільки цей метод не потребує стану, тому вивід var_dump() можна налаштувати:
enum Status: int
{
case Ok = 200;
public function __debugInfo(): array
{
return [__CLASS__ . '::' . $this->name . ' = ' . $this->value];
}
}
Обробка помилок потоків
Потоки отримують уніфіковану модель помилок. Нова контекстна опція 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 визначає понад 50 семантичних кодів помилок у enum StreamErrorCode.
Доповнення до URI Extension
Розширення URI, що з'явилося у PHP 8.5, отримує класи-будівельники, що дозволяють складати URI без створення проміжних об'єктів для кожного компонента:
$uri = new Uri\Rfc3986\UriBuilder()
->setScheme('https')
->setHost('example.com')
->setPath('/foo/bar')
->build();
RFC також додає методи getUriType() та getHostType(), а також функції процентного кодування для окремих компонентів URI.
Безпечні налаштування сесій за замовчуванням
Три налаштування сесій php.ini змінюються для нових інсталяцій:
session.use_strict_mode: з 0 на 1
session.cookie_httponly: з 0 на 1
session.cookie_samesite: з невстановленого на Lax
Laravel керує власними cookie сесій, тому більшість додатків не постраждає. Додатки, що використовують нативні PHP-сесії та покладаються на старі налаштування, мають перевірити відповідний RFC.
Додаткова інформація
Повний список завдань підготовки PHP 8.6, індекс RFC з усіма прийнятими пропозиціями для версії 8.6 та список deprecations доступні на офіційній вікі PHP.