0Pricing
PHP Academy · Lektion

PHP 8.1 Fibers

Unterbrechen Sie die Ausführung und setzen Sie sie mit nativen Fibers fort.

PHP 8.1 Fibers ist eine kostenlose PHP Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des PHP Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der PHP Academy-Kurs umfasst insgesamt 4 Lektionen.

Was Fibers Ihnen bieten

Mit PHP 8.1 wurden Fibers eingeführt: ein Kernprimitiv, mit dem Sie einen laufenden Aufruf-Stack anhalten und später an einer völlig anderen Stelle fortsetzen können. Ein Fiber ist ein vollständiger, unabhängiger Stack, den Sie an einem beliebigen Punkt suspendieren und fortsetzen können, ohne ihn abzuwickeln. Dieses fehlende Element ermöglicht es Bibliotheken, Promise-Ketten durch ein synchron wirkendes await zu ersetzen — die Grundlage der modernen APIs von ReactPHP und Amp.

Ihr erster Fiber

Erstellen Sie einen Fiber mit einem Callback, starten Sie ihn mit start() und lassen Sie ihn sich selbst mit suspend() anhalten. Am Suspendierungspunkt kehrt die Kontrolle zum Aufrufer zurück; resume() setzt die Ausführung genau dort fort.

<?php
$fiber = new Fiber(function (): void {
    echo "A: inside fiber\n";
    $received = Fiber::suspend('paused');
    echo "C: resumed with '$received'\n";
});

$value = $fiber->start();          // prints A, returns 'paused'
echo "B: fiber suspended, got '$value'\n";
$fiber->resume('hello');           // prints C
echo "D: fiber done\n";

Die vier Kernmethoden

Die API ist klein:

  • $fiber->start(...$args) — beginnt die Ausführung und gibt den ersten Suspendierungswert zurück.
  • Fiber::suspend($value) — hält den aktuellen Fiber an und übergibt $value an den Aufrufer, der ihn fortsetzt.
  • $fiber->resume($value) — setzt die Ausführung fort; $value wird zum Rückgabewert von suspend().
  • $fiber->getReturn() — liefert den Rückgabewert des Callbacks, sobald dieser beendet ist.

Werte fließen über die Suspendierungsgrenze hinweg in beide Richtungen.

Bidirektionale Wertübergabe

Ein Fiber kann eine Anfrage nach außen übergeben und eine Antwort zurückerhalten — genau darauf basiert die Übergabe von E/A-Ergebnissen durch eine Event-Schleife an suspendierte Aufgaben.

<?php
$fiber = new Fiber(function (): int {
    $a = Fiber::suspend('need first number');
    $b = Fiber::suspend('need second number');
    return $a + $b;
});

$fiber->start();        // suspends: 'need first number'
$fiber->resume(10);     // a = 10, suspends: 'need second number'
$fiber->resume(32);     // b = 32, fiber returns
echo $fiber->getReturn(), PHP_EOL; // 42

Fiber-Zustand und Introspektion

Sie können den Lebenszyklus eines Fibers abfragen. Der Aufruf von resume() bei einem beendeten Fiber löst FiberError aus. Verwenden Sie beim Erstellen eines Schedulers daher diese Prüfungen.

<?php
$fiber = new Fiber(function () { Fiber::suspend(); });
var_dump($fiber->isStarted());     // false
$fiber->start();
var_dump($fiber->isStarted());     // true
var_dump($fiber->isSuspended());   // true
var_dump($fiber->isRunning());     // false (we're outside it)
$fiber->resume();
var_dump($fiber->isTerminated());  // true

Einen kleinen Scheduler erstellen

Fibers plus eine Warteschlange ergeben einen kooperativen Scheduler. Jede Aufgabe suspendiert, um die Kontrolle abzugeben; der Scheduler arbeitet die Aufgaben im Round-Robin-Verfahren ab, bis alle abgeschlossen sind. Das ist das Grundgerüst jeder asynchronen Laufzeitumgebung.

<?php
$tasks = [];
foreach (['X', 'Y', 'Z'] as $name) {
    $tasks[] = new Fiber(function () use ($name) {
        for ($i = 1; $i <= 2; $i++) {
            echo "$name step $i\n";
            Fiber::suspend();   // give others a turn
        }
    });
}
foreach ($tasks as $t) { $t->start(); }
while ($tasks) {
    foreach ($tasks as $k => $t) {
        if ($t->isTerminated()) { unset($tasks[$k]); continue; }
        $t->resume();
    }
}

Ausnahmen über Grenzen hinweg

throwInto() (in der API als throw() in der Form $fiber->throw() bezeichnet) injiziert am Suspendierungspunkt eine Ausnahme — so meldet eine Event-Schleife einen fehlgeschlagenen E/A-Vorgang an die wartende Aufgabe zurück. Die Ausnahme tritt genau dort auf, wo der Fiber angehalten wurde.

<?php
$fiber = new Fiber(function () {
    try {
        Fiber::suspend();
    } catch (RuntimeException $e) {
        echo 'caught: ' . $e->getMessage() . PHP_EOL;
    }
});
$fiber->start();
$fiber->throw(new RuntimeException('io failed')); // prints: caught: io failed

Fibers und Generatoren

Generatoren (yield) suspendieren ebenfalls — aber nur die oberste Funktion. Um aus einem verschachtelten Helfer heraus zu warten, müssen Sie yield from bis ganz nach oben im Stack durchreichen, wodurch jede Funktion angepasst werden muss. Fibers suspendieren den gesamten Stack aus jeder Verschachtelungstiefe, sodass ein tief verschachtelter Aufruf Fiber::suspend() verwenden kann, ohne dass seine Aufrufer davon wissen. Deshalb kann await ein gewöhnlicher Funktionsaufruf statt eines yield sein.

<?php
function deep(): string {
    // No yield needed in the call chain — suspends the whole fiber
    return Fiber::suspend('awaiting from deep');
}
$f = new Fiber(fn() => print(deep() . PHP_EOL));
$f->start();
$f->resume('value injected at depth');

Die Einschränkung beim Suspendieren

Es gibt eine harte Regel: Sie können Fiber::suspend() nur innerhalb eines Fibers aufrufen. Das Suspendieren aus dem Hauptthread oder über einen C-Level-Callback hinweg, der Fibers nicht unterstützt (etwa einige Legacy-usort-Vergleiche und bestimmte interne Callbacks), löst FiberError: Cannot suspend outside of a fiber aus. Bibliotheken verbergen diese Einschränkung, indem sie sicherstellen, dass der gesamte Benutzercode innerhalb eines von der Schleife gesteuerten Fibers ausgeführt wird.

<?php
try {
    Fiber::suspend(); // main thread — illegal
} catch (FiberError $e) {
    echo $e->getMessage(), PHP_EOL; // Cannot suspend outside of a fiber
}

Wie Bibliotheken Fibers verwenden

In Anwendungscode schreiben Sie nur selten direkte Fibers. Frameworks wie Amp v3 und ReactPHP (via fibers) kapseln sie: await($promise) ruft intern Fiber::suspend() auf, registriert eine Fortsetzung bei der Event-Schleife und setzt mit resume() Ihren Fiber fort, sobald der E/A-Vorgang abgeschlossen ist. Ihr Code sieht synchron aus; die Laufzeitumgebung übernimmt das Parken und die Ablaufplanung.

<?php
// Conceptual: what an await() helper does under the hood
function await(Promise $p): mixed {
    $fiber = Fiber::getCurrent() ?? throw new Error('await() outside fiber');
    $p->then(fn($v) => $fiber->resume($v),
             fn($e) => $fiber->throw($e));
    return Fiber::suspend(); // parked until the promise settles
}

Hinweise zu Speicher und Lebenszyklus

Jeder Fiber reserviert seinen eigenen Stack, daher kostet das Erzeugen von Hunderttausenden Fibers Speicher (auch wenn sie deutlich weniger Ressourcen benötigen als Betriebssystem-Threads). Ein Fiber, der für immer suspendiert bleibt, wird nicht durch Garbage Collection eingesammelt, wenn noch etwas auf ihn verweist — ein subtiler Leak in langlebigen Servern. Außerdem wird eine Ausnahme, die der Callback eines Fibers ungefangen auslöst, aus dem Aufruf von resume()/start() weitergereicht. Der Scheduler muss resume-Aufrufe daher mit try/catch absichern.

<?php
$fiber = new Fiber(function () {
    throw new RuntimeException('boom inside fiber');
});
try {
    $fiber->start(); // exception surfaces here, at the resumer
} catch (RuntimeException $e) {
    echo 'scheduler caught: ' . $e->getMessage() . PHP_EOL;
}

Kurzer Test

Welchen entscheidenden Vorteil haben Fibers gegenüber Generatoren für asynchrone Abläufe?

Zusammenfassung

Fibers sind das Low-Level-Primitiv für Nebenläufigkeit in PHP:

  • start(), Fiber::suspend(), resume() und getReturn() halten einen vollständigen Aufruf-Stack an und setzen ihn fort; dabei werden Werte in beide Richtungen übergeben.
  • Zustandsmethoden (isSuspended, isTerminated) und throw() ermöglichen den Aufbau eines kooperativen Schedulers sowie das Einschleusen von E/A-Fehlern.
  • Im Gegensatz zu Generatoren suspendiert ein Fiber aus jeder Verschachtelungstiefe — dadurch wird ein transparentes await() möglich.
  • Sie können nur innerhalb eines Fibers suspendieren; Frameworks wie Amp und ReactPHP kapseln Fibers, sodass Ihr asynchroner Code synchron lesbar ist.

Häufig gestellte Fragen

Ist die Lektion „PHP 8.1 Fibers“ kostenlos?

Ja — der vollständige Text von „PHP 8.1 Fibers“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des PHP Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der PHP Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „PHP 8.1 Fibers“?

Unterbrechen Sie die Ausführung und setzen Sie sie mit nativen Fibers fort. Du übst PHP Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um PHP Academy zu starten?

Keine Vorkenntnisse erforderlich. PHP Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „PHP 8.1 Fibers“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser PHP Academy-Lektion Code schreiben und ausführen?

Ja. Jede PHP Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Das PHP-Konkurrenzmodell
  2. PHP 8.1 Fibers
  3. Event Loops mit ReactPHP
  4. Hochleistungsserver mit Swoole
← Zurück zu PHP Academy