До основного вмісту

Fibers у PHP: асинхронний код без розширень

PHP · 18.10.2026 · 3 хв читання
Ілюстрація до статті «Fibers у PHP: асинхронний код без розширень»

Fiber (PHP 8.1+) — це вбудований у мову механізм зупинки і відновлення виконання функції без розширень типу Swoole. Сам по собі Fiber не дає паралелізму чи неблокувального I/O — він лише керує точкою повернення, а мережеві й файлові операції без блокування додають бібліотеки планувальника, такі як Revolt чи amphp.

Що Fiber робить, а що ні

Fiber обгортає функцію в об'єкт, який можна запустити, зупинити зсередини і відновити ззовні, передаючи значення в обидва боки. Це низькорівневий примітив — перемикання контексту без створення нового процесу чи потоку ОС, у межах одного процесу PHP.

Fiber сам не робить мережевий виклик неблокувальним: без циклу подій навколо нього suspend просто зупиняє виконання до явного resume. Саме такий цикл подій (Revolt, amphp) перетворює набір Fiber у справжній асинхронний код з кількома задачами одночасно.

Мінімальний приклад: start, suspend, resume

Нижче — буквально вся механіка Fiber без бібліотек планувальника: функція зупиняється всередині, а код ззовні вирішує, коли її відновити і що передати назад.

$fiber = new Fiber(function (): void {
    $value = Fiber::suspend('started');
    echo $value, PHP_EOL;
});
$fiber->start();
$fiber->resume('resumed');

Чим це відрізняється від корутин Swoole

Swoole дає готовий цикл подій, неблокувальний ввід-вивід на рівні розширення і власний HTTP-сервер — усе це розібрано в статті про Swoole і RoadRunner. Fiber — це лише базова цеглинка мови, на якій бібліотеки рівня Revolt будують такий самий цикл подій без C-розширення, жертвуючи частиною швидкості заради переносимості на будь-який хостинг з PHP 8.1 і вище.

  • Потрібна обгортка-планувальник (Revolt, amphp) — без неї Fiber не дає конкурентності
  • Немає вбудованого неблокувального клієнта для MySQL чи Redis, як у Swoole
  • Працює в будь-якому середовищі CLI і FPM без встановлення розширення
  • Перемикання між Fiber дешевше за створення потоку, але дорожче за виклик звичайної функції
  • Винятки всередині Fiber потрібно явно перехоплювати при resume, інакше вони втрачаються

Де Fiber справді корисний на практиці

Fiber годиться там, де скрипт виконує кілька незалежних операцій очікування — кілька HTTP-запитів до зовнішніх API, кілька запитів до черги — і запущений у звичайному процесі PHP CLI, а не під Swoole. Різницю між запуском через CLI і через FPM для таких довгих скриптів розібрано в статті про PHP у cron.

Fiber не замінює черги повідомлень: він прискорює очікування всередині одного процесу, але не дає ізоляції від падіння процесу і не перезапускає задачу сам. Надійний перезапуск воркерів черг через Supervisor залишається окремою темою, розібраною в статті про черги PHP і Supervisor.

Таблиця: підходи до конкурентності в PHP

Таблиця порівнює механізми, а не швидкість — конкретна різниця у продуктивності залежить від задачі і повинна бути вимірена окремо.

ПідхідПотрібне розширенняТипова задача
Звичайний блокувальний PHPніпростий скрипт, одна задача за раз
Fiber + Revolt чи amphpнікілька незалежних HTTP-запитів у CLI-скрипті
Swooleтакдовгоживучий сервер з корутинами і власним HTTP-сервером
RoadRunnerні, окремий бінарникдовгоживучі PHP-воркери за Go-сервером

Часті питання

Чи потрібно переписувати код на Fiber заради прискорення звичайного сайту?

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

Чи можна використовувати Fiber разом зі Swoole?

Так, Swoole сам побудований на схожій ідеї перемикання контексту і надає власні корутини, які у багатьох версіях сумісні з кодом на Revolt усередині одного процесу.

Що відбувається з винятком усередині Fiber, якщо його не перехопити?

Виняток зʼявляється під час наступного виклику resume на цьому Fiber, а не в момент виникнення всередині функції — якщо викликальний код не обгортає resume у try-catch, виняток перериває виконання так само, як звичайний необроблений виняток.

Чи була стаття корисною?
← Назад до бази знань Поставити питання підтримці