Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
PHP 8.6: що готує листопадовий реліз
Новини 05 серпня 2026

PHP 8.6: що готує листопадовий реліз

PHP 8.6 виходить 19 листопада 2026 року. Feature freeze ще попереду, але основне вже у гілці, і цього разу найцікавіше - не окрема можливість, а те, як дві з них нарешті складаються докупи. Детальний огляд змін зібрав Брент Роозе; нижче - те, що з цього справді варто знати, звірене з відповідними RFC.

Часткове застосування функцій рятує оператор |>

Оператор |> приїхав ще в PHP 8.5, але користуватися ним було незручно: він вимагає callable рівно з одним параметром. Тобто strtolower(...) у пайплайн стає, а str_replace(' ', '-', ...) - ні, бо в неї три параметри. На практиці це означало замикання вручну на кожному другому кроці, і половина краси пайплайна зникала.

Часткове застосування функцій (partial function application, PFA) закриває саме цю дірку. Знак ? позначає параметр, який лишається незаповненим, а решта фіксується одразу:

$makeSlug = str_replace(' ', '-', ?);

$makeSlug('Hello World');
// Hello-World

Результат - звичайне замикання, яке можна передати куди завгодно. Але найкраще воно виглядає саме в парі з |>:

$output = 'Hello World'
  |> str_replace(' ', '-', ?)
  |> strtolower(...);

// hello-world

Автори RFC - Ларрі Гарфілд і Арно ле Блан, статус - Implemented. Якщо ви дивилися на пайплайн-оператор і не розуміли, навіщо він потрібен, то ось відповідь: без PFA він був напівфабрикатом.

Io\Poll: заміна stream_select

Друга велика річ - Polling API авторства Якуба Зеленки. Досі єдиним способом мультиплексування вводу-виводу в PHP був stream_select() з усіма його обмеженнями. Тепер зʼявився простір імен Io\Poll з класами Context, Event і StreamPollHandle:

use Io\Poll\Context;
use Io\Poll\Event;
use Io\Poll\StreamPollHandle;

$context = new Context();

$stream = stream_socket_server('tcp://0.0.0.0:8080', $errno, $errstr);
stream_set_blocking($stream, false);

$handle = new StreamPollHandle($stream);
$context->add($handle, [Event::Read], ['type' => 'server']);

while (true) {
  $watchers = $context->wait(1);
  // …
}

Два уточнення, щоб не було завищених очікувань. По-перше, це не асинхронність: жодних нових асинхронних можливостей PHP не отримує, це просто зручніший інтерфейс до того, що вже було. По-друге, вбудованого event loop немає - обгортка лишається на совісті бібліотек.

Реальний виграш тут не для прикладного коду, а для інфраструктурного: API вміє працювати з epoll і WSAPoll там, де вони доступні, тож на масштабі буде швидше за stream_select(). Найбільше з цього візьмуть ReactPHP та Amp, а всередині самого PHP - PHP-FPM і обробка сигналів у режимі ZTS.

Дрібниці, які знадобляться щодня

Вбудований clamp(). Функція, яку кожен фреймворк писав сам, тепер у ядрі. Сигнатура з RFC - clamp(mixed $value, mixed $min, mixed $max): mixed, межі включні:

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

Працює не лише з числами, а з будь-якими порівнюваними значеннями - рядками і датами теж:

clamp("a", "x", "z"); // "x"

clamp(
  value: new DateTimeImmutable('2025-01-01'),
  min: new DateTimeImmutable('2026-01-01'),
  max: new DateTimeImmutable('2026-12-31'),
); // DateTimeImmutable('2026-01-01')

Деталь, якої немає у більшості userland-реалізацій: якщо $min більший за $max або якась із меж дорівнює NAN, кидається ValueError. Тобто на відміну від саморобного тернарника, зіпсовані межі не проходять тихо.

Енум SortDirection з випадками Ascending і Descending. Поки що це просто спільний словник для бібліотек: вбудовані функції на кшталт array_multisort() чи scandir() його ще не приймають, це в планах.

Doc-коментарі до параметрів. ReflectionParameter отримав getDocComment(), тож типи можна писати біля самого параметра, а не в шапці функції:

function store(
  /** @param Book[] */
  array $books,
): void { /* … */ }

Пастка: якщо ставите коментар після параметра, він має бути перед комою, інакше не звʼяжеться. Найбільше з цього візьмуть статичні аналізатори.

__debugInfo() в енумах - тепер можна керувати тим, що показує var_dump() для енума. Плюс до рефлексії додали ReflectionProperty::isReadable() та isWriteable() з урахуванням області видимості, що стало доречним після появи хуків властивостей у PHP 8.4.

Що ще не вирішено

Одна річ зі списку новинок PHP 8.6 поки що не є доконаним фактом. RFC Readonly Property Defaults Ніка Сдота на момент написання має статус Voting, а не Implemented, тож розраховувати на цю можливість зарано.

Ідея слушна: після того як хуки властивостей дозволили описувати властивості в інтерфейсах, заборона на значення за замовчуванням для readonly почала заважати:

final class CreateBooksTable implements MigratesUp
{
  public readonly string $name = '2026-01-01_create_books_table';
}

Спочатку цю заборону зробили свідомо - readonly-властивість зі значенням за замовчуванням фактично є константою. Але з інтерфейсними хуками незмінне значення стало частиною контракту, і аргумент проти ослаб. Голосування потребує 2/3 голосів; результат варто перевірити перед тим, як закладати це в код.

Депрекейти: чим доведеться зайнятися

Пакет депрекейтів для PHP 8.6 - понад двадцять пунктів. Більшість чиститься механічно, і зробити це варто зараз, а не тоді, коли вони перетворяться на помилки в PHP 9.

Проста заміна один-в-один:

  • is_double(), is_integer(), is_long() - на is_int() та is_float();
  • doubleval() - на floatval();
  • spl_object_hash() - на spl_object_id();
  • spl_classes() - на ReflectionExtension::getClassNames();
  • $mysqli->stmt_init() - на $mysqli->prepare();
  • strcoll(), metaphone() і прапорець SORT_LOCALE_STRING.

Вимагає уваги, а не лише sed:

  • return у блоці finally - класичне джерело непомітних багів, коли повернення з finally тихо перекриває результат try;
  • CSV-методи SplFileObject (fgetcsv(), fputcsv(), setCsvControl(), getCsvControl()) - обробка CSV поїде в окреме розширення;
  • десять методів ArrayIterator (asort(), ksort(), serialize() та інші), які існували лише через спільну колись реалізацію з ArrayObject;
  • return у конструкторах і деструкторах;
  • is_subclass_of() та is_a() з allow_string: false - у такій комбінації рядок завжди давав false, тобто передавання рядка означало баг.

Окремо - зарезервовані слова: let, is, namespace як імʼя константи класу, функція з іменем readonly і константа _. Ці депрекейти зроблені під майбутній синтаксис, зокрема is тримають під можливий match.

Дефолти сесій: єдине місце, де може боляче

Це найважливіша практична зміна релізу, бо вона зачіпає застосунки, які взагалі нічого не міняли в коді. Три ini-налаштування отримали нові значення за замовчуванням:

  • session.use_strict_mode - тепер 1 замість 0;
  • session.cookie_httponly - тепер 1 замість 0;
  • session.cookie_samesite - тепер Lax замість порожнього значення.

Хто це відчує:

  • Передавання ID сесії ззовні (наприклад, обмін між піддоменами через save handler files) перестане працювати: зі строгим режимом ID без наявного файлу сесії відхиляється. Правильний шлях - записати й закрити сесію через session_write_close() на боці-джерелі до передавання ID. Власні обробники, чий validateId() завжди повертає true, змін не помітять - сюди потрапляють і стандартні обробники Redis та Memcached, які цей метод не реалізують.
  • Читання cookie сесії з JavaScript через document.cookie більше не спрацює. Якщо клієнтському коду потрібен токен для звірки запитів, це має бути окремий не-HttpOnly CSRF-токен, а не сам ID сесії.
  • Міждоменні POST-запити з cookie сесії - SP-ініційований SAML SSO, застарілі міждоменні форми. З SameSite=Lax cookie не їде на міждоменний POST, тож для таких ендпоінтів доведеться явно виставляти SameSite=None; Secure або переходити на токени.

Пом'якшує ситуацію те, що Chrome і Firefox уже давно застосовують Lax як неявний дефолт для cookie без атрибута SameSite. Тобто більшість застосунків уже живе за цими правилами, просто тепер поведінка стає однаковою в усіх браузерах і версіях PHP.

Що робити зараз

До релізу три з половиною місяці, і найкорисніше - не чекати листопада, а прогнати депрекейти. Більшість із них ловить статичний аналіз: PHPStan і Rector дадуть список замін is_integer(), spl_object_hash() і подібного за один прохід, і це можна злити одним рутинним PR без ризику.

Окремо варто перевірити сесії - це єдине, що може зламатися без жодних змін у вашому коді. Якщо у вас є SAML SSO, міждоменні форми або обмін сесією між піддоменами, поставте потрібні значення session.* явно в php.ini вже зараз: тоді оновлення на 8.6 нічого не змінить, бо ви більше не покладаєтеся на дефолти.

А от закладати в код часткове застосування функцій ще рано - воно з'явиться лише в 8.6, і код із ? просто не розпарситься на 8.5. Те саме стосується значень за замовчуванням для readonly: там ще й голосування не завершене.

33

Читати в документації

Коментарі

Увійдіть, щоб залишити коментар

Будьте першим, хто залишить коментар!

Читайте також

Filament v5.10.0
Новини 12 жовтня 2026

Filament v5.10.0: сітка в rich editor, скелетони таблиць і десятки виправлень

Вийшов Filament v5.10.0: елементи керування сіткою в rich editor, допоміжний контент для віджетів-графіків, скелетони завантаження таблиць, submitOnCompletion() для OneTimeCodeInput та багато виправлень авторизації, доступності й стану.

15
Laravel AI SDK на практиці
Новини 09 жовтня 2026

Laravel AI SDK на практиці: агент, що стоїть за There There

Фрік Ван дер Гертен розповідає, як у Spatie побудували AI-шар хелпдеска There There на Laravel AI SDK: клас агента, інструменти з типізованою JSON-схемою та делегування роботи звичайним domain-діям.

11

Вакансії за темою

Stape Нова
Вчора

PHP Team Lead

Керівник команди PHP-розробників, який наймає й розвиває бекенд-інженерів, планує завдання і ресурси, контролює передбачуваність поставок та усуває ризики і блокери. Також потрібно розробляти нові функції, оптимізувати продуктивність і масштабування high-load систем, проводити code review та брати участь в архітектурних рішеннях. Стек: PHP, Symfony, MySQL, PostgreSQL, Redis, RabbitMQ, REST API. Вимоги: 5+ років досвіду з PHP, 3+ роки з Symfony, 2+ роки керівництва командою, досвід роботи з high-

Middle PHP Developer (SQL / Oracle)

Розробка, доопрацювання та підтримка корпоративної системи «Універсал» на PHP і JavaScript: нові модулі, форми, звіти, бізнес-логіка, REST API та інтеграції. Робота з Oracle Database і PL/SQL, написання й оптимізація SQL-запитів, участь у міграції з «Універсал 7» на «Універсал 9». Вимоги: від 2-3 років комерційного досвіду на PHP, впевнене знання SQL, практичний досвід з JavaScript та базовий з Oracle, розуміння REST API, JSON/XML і Git.

Senior PHP Backend Developer

Розробник створюватиме та підтримуватиме інтерфейси веб-застосунку на PHP, розширюватиме наявні модулі, писатиме модульний і масштабований код та бере участь в оцінці й пріоритизації завдань. Ключовий стек: PHP, Laravel, SQL (PostgreSQL, MySQL), NoSQL (MongoDB, Redis), Docker, CI/CD. Вимоги: понад 5 років досвіду PHP backend-розробником, написання тестів (PHPUnit), якісна документація, англійська B1.