Menu
Coddy logo textTech

Fibers (PHP 8.1)

Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy — Lektion 60 von 91.

Fibers sind ein PHP 8.1-Feature, das die unterbrechbare Codeausführung ermöglicht. Im Gegensatz zu regulären Funktionen, die von Anfang bis Ende durchlaufen, kann eine Fiber sich selbst mitten in der Ausführung pausieren und später fortgesetzt werden, wobei ihr Zustand between den Pausen erhalten bleibt.

Erstellen Sie einen Fiber, indem Sie ein callable an die Fiber-Klasse übergeben, und starten Sie ihn dann mit start():

<?php
$fiber = new Fiber(function(): void {
    echo "Step 1\n";
    Fiber::suspend();
    echo "Step 2\n";
});

$fiber->start();
echo "Between steps\n";
$fiber->resume();

Ausgabe:

Step 1
Between steps
Step 2

Der Fiber läuft, bis er Fiber::suspend() erreicht, dann kehrt die Steuerung zum Hauptcode zurück. Der Aufruf von resume() setzt die Ausführung dort fort, wo sie pausiert wurde.

Fibers können auch Werte übergeben, wenn sie unterbrochen (suspended) und fortgesetzt (resumed) werden:

<?php
$fiber = new Fiber(function(): string {
    $value = Fiber::suspend("paused");
    return "Received: $value";
});

$suspended = $fiber->start();
echo "$suspended\n";

$result = $fiber->resume("hello");
echo $result;

Ausgabe:

paused
Received: hello

Fibers sind das Fundament für asynchrone PHP-Frameworks. Obwohl Sie sie in den meisten Anwendungen nicht direkt verwenden werden, hilft das Verständnis von ihnen bei der Arbeit mit Async-Bibliotheken, die concurrently Ausführungen wie HTTP-Anfragen oder Datenbankabfragen ohne Blockierung verarbeiten.

challenge icon

Aufgabe

Einfach

Lassen Sie uns einen Task-Scheduler bauen, der zeigt, wie Fibers die Ausführung anhalten und fortsetzen können, während Daten zwischen der Fiber und dem Hauptcode übergeben werden. Sie erstellen ein System, in dem Aufgaben unterbrochen werden können, sodass in der Zwischenzeit andere Arbeiten stattfinden können.

Sie organisieren Ihren Code in zwei Dateien:

  • TaskRunner.php — Erstellen Sie eine TaskRunner-Klasse, die die Fiber-Funktionalität zum Ausführen von Aufgaben kapselt. Die Klasse sollte:
    • Eine private Eigenschaft besitzen, um eine Fiber-Instanz zu speichern
    • Einen Aufgabennamen (string) in ihrem Konstruktor mittels Constructor Promotion akzeptieren
    • Eine Methode createTask(callable $task) haben, die eine neue Fiber mit dem übergebenen Callable erstellt und sie speichert
    • Eine Methode start() haben, die die Fiber startet und den Wert zurückgibt, mit dem die Fiber pausiert (oder den finalen Rückgabewert)
    • Eine Methode continue(mixed $value) haben, die die Fiber mit dem übergebenen Wert fortsetzt und den nächsten pausierten Wert (oder den finalen Rückgabewert) zurückgibt
    • Eine Methode isFinished(): bool haben, die zurückgibt, ob die Fiber beendet ist
  • main.php — Binden Sie die Datei TaskRunner ein. Sie erhalten zwei Eingaben: einen Aufgabennamen und eine Nachricht, die an die Fiber gesendet werden soll.

    Erstellen Sie einen TaskRunner mit dem gegebenen Aufgabennamen und verwenden Sie dann createTask(), um eine Aufgabe zu definieren, die:

    1. Zuerst mit dem String "Waiting for input" pausiert
    2. Einen Wert empfängt, wenn sie fortgesetzt wird
    3. "Completed: [received value]" zurückgibt

    Starten Sie die Aufgabe und geben Sie aus, was sie beim ersten Pausieren zurückgibt. Geben Sie dann "Processing..." aus, um zu zeigen, dass zwischen den Fiber-Pausen Arbeit stattfindet. Fortsetzen Sie schließlich die Fiber, indem Sie die eingegebene Nachricht übergeben, und geben Sie das Endergebnis aus.

Diese Herausforderung zeigt, wie Fibers kooperatives Multitasking ermöglichen — Ihre Aufgabe pausiert sich selbst an einem geeigneten Punkt, der Hauptcode führt andere Arbeiten aus und setzt die Aufgabe dann mit neuen Daten fort. Die Fiber behält ihren Zustand durchgehend bei und macht genau dort weiter, wo sie aufgehört hat.

Probier es selbst

<?php

require_once 'TaskRunner.php';

// Eingaben lesen
$taskName = trim(fgets(STDIN));
$message = trim(fgets(STDIN));

// TODO: Erstelle einen TaskRunner mit dem gegebenen Task-Namen

// TODO: Verwende createTask(), um einen Task zu definieren, der:
// 1. First suspends with the string "Waiting for input"
// 2. Einen Wert empfängt, wenn er fortgesetzt wird
// 3. "Completed: [received value]" zurückgibt

// TODO: Starte den Task und gib aus, was er zurückgibt, wenn er zum ersten Mal suspendiert

// TODO: Gib "Processing..." aus, um zu zeigen, dass zwischen Fiber-Pausen Arbeit stattfindet

// TODO: Setze den Fiber fort, indem du die Nachrichteneingabe übergibst

// TODO: Gib das Endergebnis aus

?>
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung