Как использовать Fibers для асинхронности?php-73

Fibers — это новая возможность PHP 8.1+, предоставляющая легковесные корутины для управления выполнением кода без многопоточности. Рассмотрим детально:

1. Основные концепции Fibers

  • Не являются потоками — выполняются в одном потоке
  • Кооперативная многозадачность — управление передается явно
  • Полноценный стек вызовов — в отличие от генераторов

2. Базовый пример использования

$fiber = new Fiber(function(): void {
    echo "Fiber start\n";
    Fiber::suspend();
    echo "Fiber end\n";
});

echo "Before start\n";
$fiber->start();  // Выведет "Fiber start"
echo "After start\n";
$fiber->resume(); // Выведет "Fiber end"
echo "After resume\n";

Вывод:

Before start
Fiber start
After start
Fiber end
After resume

3. Передача данных в/из Fiber

$fiber = new Fiber(function($param): string {
    $value = Fiber::suspend($param . ' processed');
    return $value . ' returned';
});

$initial = $fiber->start('input'); // Приостановка после suspend
echo $initial; // "input processed"

$final = $fiber->resume('new'); // Возобновление с передачей 'new'
echo $final; // "new returned"

4. Интеграция с event loop

class Scheduler {
    private array $fibers = [];

    public function add(Fiber $fiber): void {
        $this->fibers[] = $fiber;
    }

    public function run(): void {
        while (!empty($this->fibers)) {
            $fiber = array_shift($this->fibers);

            if (!$fiber->isTerminated()) {
                $this->add($fiber);
                $fiber->resume();
            }
        }
    }
}

$scheduler = new Scheduler();

$fiber1 = new Fiber(function() {
    echo "Task 1 start\n";
    Fiber::suspend();
    echo "Task 1 end\n";
});

$fiber2 = new Fiber(function() {
    echo "Task 2 start\n";
    Fiber::suspend();
    echo "Task 2 end\n";
});

$scheduler->add($fiber1);
$scheduler->add($fiber2);
$scheduler->run();

5. Обработка ошибок

try {
    $fiber = new Fiber(function(): void {
        throw new Exception('Fiber error');
    });
    $fiber->start();
} catch (Exception $e) {
    echo "Caught: " . $e->getMessage();
}

6. Best Practices

  1. Не для CPU-bound задач — Fibers не ускоряют вычисления
  2. Идеально для I/O операций — ожидание БД, API, файлов
  3. Комбинируйте с генераторами для сложных сценариев
  4. Избегайте глубоких стеков — сохраняйте легковесность

7. Сравнение с другими подходами

Особенность Fibers Генераторы Многопоточность
Контекст выполнения Полный стек Только yield Полный стек
Параллелизм Кооперативный Кооперативный Истинный
Потребление памяти Низкое Очень низкое Высокое
Сложность Средняя Низкая Высокая

Резюмируем:

Fibers в PHP — это:

  • Мощный инструмент для управления выполнением кода
  • Альтернатива генераторам с полным стеком вызовов
  • Основа для асинхронных фреймворков (ReactPHP, Amp)
  • Не требует расширений — встроено в ядро PHP 8.1+
  • Требует ручного управления выполнением

Для реальных проектов рекомендуется использовать Fibers в сочетании с существующими асинхронными библиотеками, а не реализовывать свой планировщик. Это особенно полезно для:

  • Микросервисных архитектур
  • Высоконагруженных API
  • Долгих I/O операций