dmitry_kv15 May 2026 23:41

PHP 8.1 добавил Fibers, но до сих пор вижу много непонимания что это такое и когда их применять. Попробую объяснить на работающем примере который можно запустить прямо в sandbox.

Fiber это не многопоточность. Это кооперативная многозадачность: вы сами говорите когда передать управление через Fiber::suspend().

PHP
<?php
// Простой пример: два "процесса" чередуются
$taskA = new Fiber(function (): void {
echo "A: старт\n";
Fiber::suspend();
echo "A: продолжение\n";
Fiber::suspend();
echo "A: завершение\n";
});
$taskB = new Fiber(function (): void {
echo "B: старт\n";
Fiber::suspend();
echo "B: продолжение\n";
Fiber::suspend();
echo "B: завершение\n";
});
// Простой планировщик
$fibers = [$taskA, $taskB];
foreach ($fibers as $fiber) {
$fiber->start();
}
while (true) {
$anyRunning = false;
foreach ($fibers as $fiber) {
if ($fiber->isSuspended()) {
$fiber->resume();
$anyRunning = true;
}
}
if (!$anyRunning) {
break;
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Запустите. Вывод будет: A старт, B старт, A продолжение, B продолжение, A завершение, B завершение. Никакой параллельности, просто чередование.

Практический смысл: генераторы потоков данных, реализация async/await поверх event loop, корутины без Swoole. Не стоит тащить Fibers ради простых задач где хватит обычного цикла.

Replies (2)
andriy_m16 May 2026 00:00

Хорошее объяснение. Добавлю практический пример: передача значений между fiber и основным кодом через suspend/resume:

PHP
<?php
$producer = new Fiber(function (): void {
$items = ['apple', 'banana', 'cherry', 'date'];
foreach ($items as $item) {
Fiber::suspend($item); // передаем значение наружу
}
});
// Первый запуск
$value = $producer->start();
while ($producer->isSuspended()) {
echo "Получено: $value\n";
$value = $producer->resume(); // получаем следующее значение
}
// Вывод:
// Получено: apple
// Получено: banana
// Получено: cherry
// Получено: date
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

По сути это генератор на минималках. Разница с yield: Fiber работает в своем стеке вызовов, можно вызывать suspend() из глубоко вложенных функций, а не только из тела функции-генератора.

0
katedev16 May 2026 03:12

Еще один практичный сценарий: обработка большого файла построчно без загрузки в память, с возможностью паузы.

PHP
<?php
function lineReader(string $content): Fiber
{
return new Fiber(function () use ($content): void {
$lines = explode("\n", $content);
foreach ($lines as $lineNum => $line) {
if (trim($line) !== '') {
Fiber::suspend([$lineNum + 1, $line]);
}
}
});
}
$content = "first line\nsecond line\n\nfourth line\nfifth line";
$reader = lineReader($content);
$data = $reader->start();
while ($reader->isSuspended()) {
[$num, $line] = $data;
echo "Строка $num: $line\n";
// Здесь можно сделать что угодно перед следующей строкой
// В реальном коде: запись в БД, HTTP запрос, и т.д.
$data = $reader->resume();
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

В реальном приложении вместо explode будет fgets() из файлового дескриптора, и тогда это полноценный ленивый ридер.

0
Write a reply
Markdown. ```php blocks are runnable.