ファイバー

ファイバーの概要

ファイバー(Fibers) は、完全なスタックを持つ、停止可能な関数です。 ファイバー はコールスタック中のどこからでも停止することができますし、 後に再開されるまで実行を停止したままにできます。

ファイバーは実行スタック全体を停止するので、 関数を直接呼び出している側は、関数の呼び出し方を変更する必要はありません。

実行スタック中のどこからでも、 Fiber::suspend を使って実行を停止できます。 (つまり、 Fiber::suspend の呼び出しは、 深くネストされた関数のコールスタックの中から行っても構いませんし、 呼び出しが全く存在しなくても構いません)

スタックを持たない Generator と異なり、 個々の Fiber は自分のコールスタックを持ちます。 これによって、深くネストされた関数のコールスタックの中からでも 関数を停止できます。 停止ポイントを宣言した (つまり、 Fiber::suspend を呼び出した) 関数は、 yield を使った、Generator のインスタンスを返さなければならない関数と異なり、 戻り値の型を宣言する必要はありません。

ファイバーは任意の関数をコールしている間に停止できます。 これには、PHP VM の中からコールされた関数も含みます。 たとえば、array_map に渡した関数や、 foreach によってコールされる、Iterator オブジェクトのメソッドなどです。

いったんファイバーが停止されると、 ファイバーの実行は Fiber::resume に任意の値を渡すか、 Fiber::throw を使ってファイバーに例外をスローさせることで再開できます。 再開される時は、 Fiber::suspend から値が返されます(または、例外がスローされます)。

注意: 現状の制限により、 ファイバーをオブジェクトのデストラクタ中で切り替えることはできません。

例1 ファイバーの基本的な使い方

<?php
$fiber = new Fiber(function (): void {
   $value = Fiber::suspend('fiber');
   echo "Value used to resume fiber: ", $value, PHP_EOL;
});

$value = $fiber->start();

echo "Value from fiber suspending: ", $value, PHP_EOL;

$fiber->resume('test');
?>

上の例の出力は以下となります。

Value from fiber suspending: fiber
Value used to resume fiber: test