Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
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: там ще й голосування не завершене.

34

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

Коментарі

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

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

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

Новини 04 листопада 2026

Laravel 13.40: довгі завдання черги, insertBefore() для middleware і strict для запиту

Laravel 13.40.0 додає Queue::whenJobRunsLongerThan() і Schedule::whenTaskRunsLongerThan() для завдань черги та планувальника, що виконуються задовго, а також insertBefore() і insertAfter() для вбудованого стеку middleware. Крім того - прапорець strict для $request->integer() і string() та DB::hasCommitId() для перевірки реплік.

2
Новини 04 листопада 2026

Вразливість у Concurrency: вивід задачі міг призвести до виконання коду в Laravel

Laravel 13.40.0 і 12.71.0 закривають вразливість у драйвері process фасаду Concurrency: задача, яка друкує текст від користувача, могла підробити свій результат, а батьківський процес робив його unserialize(). Пояснюємо, кого це стосується і що зробити до оновлення.

3

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

Middle PHP developer

Middle PHP розробник для високонавантаженої веб-платформи Social Casino/Online Casino: розвиток продукту, перехід монолітного проєкту на мікросервіси (Symfony), оптимізація баз даних, написання unit та functional тестів. Стек: PHP 7.4, Symfony 4, Yii, PostgreSQL 14, Redis, RabbitMQ, NGINX. Вимоги: 3-4+ роки продуктового досвіду з PHP, Yii, Symfony, PostgreSQL, розуміння REST API, Git, ООП та SOLID. Досвід з брокерами повідомлень і DDD буде плюсом.

Tech Lead — Fintech

Tech Lead для фінтех-платформи бізнес-витрат і платежів: активна розробка, архітектурні рішення, стабільність продакшену та менторство команди. Ключовий стек: PHP, Laravel/Lumen, MySQL, Redis, Docker, знання JavaScript (Vue.js, React на базовому рівні). Вимоги: розуміння життєвого циклу карткових транзакцій і криптовалют, досвід побудови надійних фінансових систем (баланси, звірка, аудит, безпечні API), DevOps-навички на Linux.

Bewort Нова
Вчора

Senior Full-Stack Developer (PHP/Laravel, Vue)

Розробка та розвиток ключових функцій корпоративної платформи на Laravel з обробкою бекенду та фронтенду на Vue. Потрібні глибокі знання внутрішньої архітектури фреймворку, досвід застосування SOLID, DDD, подій і черг, а також досвід роботи зі складними проєктами. Обов'язкове активне використання AI-інструментів для написання коду та англійська не нижче B2. Переваги: досвід із Vue, мультитенантними SaaS, AWS, CI/CD та LLM-інтеграціями.

Пакети за темою

Kalimera

welldigit/kalimera

Interactive installer that scaffolds Laravel applications the Well Digit way.

v1.0.0 16