---
title: "Що нового у PHP 8.6"
url: https://laravelukraine.com/blog/shho-novogo-u-php-86
date: 2026-09-16
source: https://laravel-news.com/php-8-6?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed%3A+laravelnews
---

# Що нового у PHP 8.6

Щорічний реліз 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, яке приймає решту параметрів. Плейсхолдер `?` позначає один аргумент для заповнення пізніше, а `...` замінює всі решту аргументів:

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

Отриманий closure зберігає імена параметрів, типи та значення за замовчуванням оригінальної функції. Аргументи, які ви надаєте, обчислюються під час створення часткового застосування, а не під час його виклику. Наступний RFC уточнив, що кожен плейсхолдер `?` стає обов'язковим параметром closure, навіть якщо оригінальний параметр був опціональним.

Попередня версія цієї пропозиції була відхилена у 2021 році. RFC версії 2 пройшов з результатом 33 голоси за і 0 проти.

## Функція clamp()

Нова функція `clamp()` повертає значення, якщо воно потрапляє в межі, або найближчу межу, якщо ні:

```php
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-клас, що представляє проміжок часу у стилі секундоміра з точністю до наносекунди. Він має фабричні методи для кожної одиниці виміру, методи для арифметичних операцій та підтримку порівняння:

```php
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 фіксованим значенням:

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

RFC лише знімає обмеження. Семантика readonly залишається незмінною, тому властивість все ще не можна перепризначити після ініціалізації.

## DocComments для параметрів функцій

Тепер doc-коментарі можуть розміщуватися безпосередньо над параметром, а `ReflectionParameter::getDocComment()` їх повертає. Це дозволяє уникнути повторення імені параметра у тезі `@param` над функцією:

```php
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:

```php
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:

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

## Enum можуть реалізувати __debugInfo()

Коли enum з'явилися у версії 8.1, їм не дозволялося визначати більшість магічних методів. PHP 8.6 знімає це обмеження для `__debugInfo()`, оскільки цей метод не потребує стану, тому вивід `var_dump()` можна налаштувати:

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

## Обробка помилок потоків

Потоки отримують уніфіковану модель помилок. Нова контекстна опція `error_mode` дозволяє вибирати між поточними попередженнями, винятками або тишею, а `stream_last_errors()` повертає структуровані об'єкти `StreamError` для останньої операції:

```php
$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 без створення проміжних об'єктів для кожного компонента:

```php
$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.
