PHP Fibers - leichte Nebenlaeufigkeit

PHP ist traditionell synchron. Ein Request, ein Ausführungspfad, fertig. Mit PHP 8.1 kamen Fibers — eine Möglichkeit für kooperative Nebenläufigkeit ohne Threads.

Was Fibers sind

Fibers sind keine Threads. Es läuft kein Code wirklich parallel.
Eine Fiber kann die Kontrolle freiwillig abgeben (Fiber::suspend()) und später fortgesetzt werden. Das ist kooperatives Multitasking.

$fiber = new Fiber(function (): void {
    echo "Fiber started\n";
    $value = Fiber::suspend('first suspension');
    echo "Resumed with: $value\n";
    Fiber::suspend('second suspension');
    echo "Fiber done\n";
});

$result1 = $fiber->start();      // gibt 'first suspension' zurück
echo "Main: $result1\n";

$result2 = $fiber->resume('hello');  // gibt 'second suspension' zurück
echo "Main: $result2\n";

$fiber->resume();

Output:

Fiber started
Main: first suspension
Resumed with: hello
Main: second suspension
Fiber done

Wann Fibers sinnvoll sind

Für die meisten PHP-Anwendungen: gar nicht. Request/Response in FPM braucht keine Fibers.

  • Sinnvoll für:
  • Frameworks die auf non-blocking I/O setzen (ReactPHP, Revolt/EventLoop)
  • CLI-Anwendungen die mehrere I/O-Operationen parallel warten lassen wollen
  • Streaming-Anwendungen

Praktisches Beispiel: mehrere HTTP-Requests gleichzeitig

function fetchUrl(string $url): string
{
    // vereinfacht — in der Praxis mit non-blocking I/O
    return file_get_contents($url);
}

$urls = [
    'https://api1.example.com/data',
    'https://api2.example.com/data',
    'https://api3.example.com/data',
];

$fibers = array_map(function (string $url) {
    return new Fiber(function () use ($url): string {
        Fiber::suspend();  // Startpunkt
        return fetchUrl($url);
    });
}, $urls);

// Alle starten
foreach ($fibers as $fiber) {
    $fiber->start();
}

// Alle zu Ende führen und Ergebnisse sammeln
$results = array_map(fn($f) => $f->resume(), $fibers);

Revolt EventLoop

Für echte non-blocking I/O in PHP:

composer require revolt/event-loop
use Revolt\EventLoop;

EventLoop::delay(1.0, function (): void {
    echo "Nach 1 Sekunde\n";
});

EventLoop::delay(0.5, function (): void {
    echo "Nach 0.5 Sekunden\n";
});

EventLoop::run();
// Output: Nach 0.5 Sekunden, Nach 1 Sekunde

Fibers sind das Fundament auf dem moderne asynchrone PHP-Bibliotheken gebaut werden. Für normales Web-PHP bleibt FPM die richtige Wahl.