ファイバー (PHP 8.1)
CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 60/91。
ファイバー (Fibers) は、中断可能なコード実行を可能にする PHP 8.1 の機能です。最初から最後まで実行される通常の関数とは異なり、ファイバーは実行の途中で自身を一時停止し、後で再開することができます。また、一時停止の間もその状態を保持します。
Fiberクラスにコーラブルを渡してファイバーを作成し、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();
出力:
Step 1
Between steps
Step 2ファイバーは Fiber::suspend() に達するまで実行され、その後、制御がメインコードに戻ります。resume() を呼び出すと、中断した箇所から実行が再開されます。
ファイバーは、中断(suspend)や再開(resume)の際に値を渡すこともできます:
<?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;
出力:
paused
Received: helloファイバー(Fibers)は、非同期PHPフレームワークの基盤です。ほとんどのアプリケーションで直接使用することはありませんが、HTTPリクエストやデータベースクエリなどの並行操作をブロッキングせずに処理する非同期ライブラリを扱う際には、それらを理解しておくと役立ちます。
チャレンジ
簡単ファイバーが実行を一時停止および再開し、ファイバーとメインコードの間でデータをやり取りする方法を示すタスクスケジューラを構築しましょう。タスクを中断できるようにし、その間に他の処理を行えるシステムを作成します。
コードは2つのファイルに分けて構成します:
TaskRunner.php— タスクを実行するためのファイバー機能をラップするTaskRunnerクラスを作成します。このクラスは以下の要件を満たす必要があります:Fiberインスタンスを保持するためのプライベートプロパティを持つこと- コンストラクタのプロパティ昇格(constructor promotion)を使用して、タスク名(文字列)を受け取ること
- 与えられたコーラブルで新しい Fiber を作成し、それを保存する
createTask(callable $task)メソッドを持つこと - ファイバーを開始し、ファイバーが中断(suspend)した際の値(または最終的な戻り値)を返す
start()メソッドを持つこと - 指定された値でファイバーを再開し、次の中断された値(または最終的な戻り値)を返す
continue(mixed $value)メソッドを持つこと - ファイバーが終了したかどうかを返す
isFinished(): boolメソッドを持つこと
main.php— TaskRunner ファイルをインクルードします。2つの入力(タスク名とファイバーに送信するメッセージ)を受け取ります。指定されたタスク名で
TaskRunnerを作成し、createTask()を使用して以下の処理を行うタスクを定義します:- 最初に文字列
"Waiting for input"で中断(suspend)する - 再開時に値を受け取る
"Completed: [received value]"を返す
タスクを開始し、最初に中断したときに返される内容を出力します。次に、ファイバーの一時停止中に行われる作業を示すために
"Processing..."と出力します。最後に、入力されたメッセージを渡してファイバーを再開し、最終的な結果を出力します。- 最初に文字列
このチャレンジは、ファイバーがいかに協調的マルチタスクを可能にするかを示しています。タスクは適切なタイミングで自身を一時停止し、メインコードが他の作業を行い、その後新しいデータでタスクを再開します。ファイバーはその間状態を維持し、中断した場所から正確に再開します。
チートシート
ファイバー(Fiber)は、PHP 8.1以降で中断可能なコード実行を可能にします。通常の関数とは異なり、ファイバーは実行の途中で一時停止し、その状態を維持したまま後で再開することができます。
Fiber クラスにコーラブル(callable)を渡してファイバーを作成し、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();
ファイバーは Fiber::suspend() まで実行され、その後、制御がメインコードに戻ります。中断した箇所から実行を継続するには、resume() を呼び出します。
ファイバーは、中断時や再開時に値を渡すことができます:
<?php
$fiber = new Fiber(function(): string {
$value = Fiber::suspend("paused");
return "Received: $value";
});
$suspended = $fiber->start();
$result = $fiber->resume("hello");
主なメソッド:
start()— ファイバーの実行を開始しますFiber::suspend($value)— 実行を一時停止し、呼び出し元に値を返しますresume($value)— 実行を継続し、ファイバーに値を渡しますisTerminated()— ファイバーが終了したかどうかを確認します
自分で試してみよう
<?php
require_once 'TaskRunner.php';
// 入力を読み込む
$taskName = trim(fgets(STDIN));
$message = trim(fgets(STDIN));
// TODO: 指定されたタスク名でTaskRunnerを作成する
// TODO: createTask()を使用して、以下のタスクを定義する:
// 1. 最初に文字列 "Waiting for input" で中断する
// 2. 再開時に値を受け取る
// 3. "Completed: [受け取った値]" を返す
// TODO: タスクを開始し、最初に中断したときに返される内容を表示する
// TODO: ファイバーの休止の間に行われている作業を示すために "Processing..." を表示する
// TODO: メッセージ入力を渡してファイバーを継続する
// TODO: 最終的な結果を表示する
?>このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
10オブジェクト指向の高度な概念
コンポジション vs 継承依存性の注入 (Dependency Injection)匿名クラスEnum (PHP 8.1)ファイバー (PHP 8.1)オブジェクトのクローン徹底解説ジェネレータとイテレータ