Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】Fiber::resume()メソッドの使い方

resumeメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

resumeメソッドは、一時停止中のファイバーの実行を再開するメソッドです。PHP 8.1で導入されたファイバーは、プログラムの実行フローを途中で一時停止し、後から任意のタイミングで再開できる軽量な並行処理の仕組みを提供します。このresumeメソッドは、主にFiber::suspend()メソッドによって実行が一時停止されたファイバーに対して使用されます。

具体的には、Fiber::suspend()が呼び出されると、ファイバーの実行は中断され、その時点でファイバーの実行を起動した側(親コンテキスト)に制御が戻ります。その後、親コンテキストからFiber::resume()を呼び出すことで、中断された箇所からファイバーの実行が再開されます。resume()メソッドには任意の値を引数として渡すことができ、その値はFiber::suspend()の戻り値としてファイバー内部で受け取ることができます。同様に、Fiber::suspend()から値を返すと、その値はFiber::resume()の戻り値として親コンテキストで受け取れます。

ファイバーはFiber::STATUS_SUSPENDED状態にある場合にのみresume()を呼び出すことができます。もし、実行中のファイバー(Fiber::STATUS_RUNNING)や、既に完了したファイバー(Fiber::STATUS_TERMINATED)に対してresume()を試みると、FiberError例外が発生しますので注意が必要です。このメソッドは、非同期処理の待機や協調的なマルチタスク処理、複雑なジェネレータのような振る舞いを実装する際に非常に有用です。

構文(syntax)

1<?php
2
3$fiber = new Fiber(function (): void {
4    Fiber::suspend();
5});
6
7$fiber->start();
8$fiber->resume("Value to pass.");

引数(parameters)

mixed $value = null

  • mixed $value = null: Fiber を resume する際に渡す値。デフォルトは null。

戻り値(return)

mixed

Fiber::resume() メソッドは、Fiber の実行を再開した際の戻り値を返します。これは、Fiber が yield された値、または Fiber の実行が完了した際の最終的な戻り値になります。

サンプルコード

PHP Fiber::resume() で値を渡して再開する

1<?php
2
3/**
4 * Fiber::resume() のサンプルコード。
5 *
6 * Fiber を再開し、値を渡す。
7 */
8
9function create_fiber(mixed $initialValue): Fiber
10{
11    return new Fiber(function (mixed $value) use ($initialValue): mixed {
12        echo "Fiber: 開始\n";
13        $received_value = Fiber::suspend($initialValue); // Fiber を中断し、初期値を返す
14        echo "Fiber: 中断から再開、受信した値: " . $received_value . "\n";
15        return $value; // 最後に渡された値を返す
16    });
17}
18
19// Fiber の初期値を設定
20$initial_value = "初期値";
21
22// Fiber を作成
23$fiber = create_fiber($initial_value);
24
25// Fiber が中断しているか確認
26echo "Fiber の状態: " . ($fiber->isSuspended() ? '中断' : '実行中') . "\n";
27
28// Fiber を開始し、初期値を受け取る
29$result1 = $fiber->resume();
30echo "main: Fiber から受信した値: " . $result1 . "\n";
31
32// Fiber が中断しているか確認
33echo "Fiber の状態: " . ($fiber->isSuspended() ? '中断' : '実行中') . "\n";
34
35
36// Fiber を再開し、値を渡す
37$result2 = $fiber->resume("再開時の値");
38echo "main: Fiber から受信した値: " . $result2 . "\n";
39
40// Fiber が完了しているか確認
41echo "Fiber の状態: " . ($fiber->isTerminated() ? '完了' : '実行中') . "\n";
42
43// Fiber の戻り値を取得
44echo "Fiber の戻り値: " . $fiber->getReturn() . "\n";

Fiber::resume() は、PHP 8 で導入された Fiber クラスのメソッドで、中断された Fiber を再開するために使用します。

このサンプルコードでは、create_fiber() 関数内で Fiber を作成しています。Fiber は、Fiber::suspend() によって中断され、その際に $initialValue が返されます。

$fiber->resume() を最初に呼び出すと、Fiber が開始され、Fiber::suspend() で指定された初期値(この例では "初期値")が返されます。この時点では、Fiber は Fiber::suspend() の実行後で中断状態になっています。

次に $fiber->resume("再開時の値") を呼び出すと、Fiber が中断状態から再開されます。resume() に渡された "再開時の値" は、Fiber::suspend() の戻り値として Fiber 内部で受け取られます。Fiber 内では、受け取った値が出力され、最後に resume() を呼び出す前に設定された $value (この例では"初期値")がFiberの戻り値として返されます。

Fiber::resume() の引数 $value は、中断された Fiber に渡す値です。戻り値は、Fiber 内で Fiber::suspend() が返す値、または Fiber の処理が完了した場合の Fiber 関数の戻り値です。このサンプルコードでは、Fiber が完了した後に $fiber->getReturn() で Fiber の戻り値を取得しています。

Fiber::resume()は、中断されたFiberを再開させるメソッドです。引数$valueは、Fiberの中断箇所(Fiber::suspend())で受け取ることができます。

このサンプルコードでは、最初にFiber::resume()を引数なしで呼び出していますが、これはFiberの最初の実行を開始する役割も果たします。2回目以降のFiber::resume()で引数を渡すと、Fiber内でFiber::suspend()が返した値として扱われます。

Fiberが完了すると、Fiber::resume()はFiber内で最後にreturnされた値を返します。Fiberが完了したかどうかは、Fiber::isTerminated()で確認できます。また、完了後のFiberのreturn値は、Fiber::getReturn()で取得できます。Fiberは一度完了すると、再度resumeすることはできませんので注意してください。

PHP Fiber::resume で実行を再開する

1<?php
2
3/**
4 * Fiber::resume() のサンプルコード
5 */
6
7// Fiberを定義
8$fiber = new Fiber(function (string $name): string {
9    // Fiberを中断し、値を返す
10    $greeting = Fiber::suspend("Hello, ");
11    return $greeting . $name . "!";
12});
13
14// Fiberを開始し、最初のsuspendまで実行
15$result = $fiber->start("World"); // "World" は Fiber の引数
16
17// suspend で返された値を確認
18echo "Fiber からの最初の戻り値: " . $result . PHP_EOL; // Fiber からの最初の戻り値: Hello,
19
20// Fiberを再開し、値を渡す
21$finalResult = $fiber->resume("Goodbye, "); // "Goodbye, " は suspend からの戻り値
22
23// Fiberの実行結果を表示
24echo "Fiber の最終的な戻り値: " . $finalResult . PHP_EOL; // Fiber の最終的な戻り値: Goodbye, World!

Fiber::resume()メソッドは、中断されたFiberを再開させるためのものです。このメソッドは、Fiberクラスに所属しており、PHP 8以降で使用できます。引数$valueは、中断されたFiberに渡す値で、型はmixed型です。省略した場合はnullが渡されます。この値は、Fiber内でFiber::suspend()によって中断された箇所で、その戻り値として利用できます。Fiber::resume()メソッドの戻り値もmixed型であり、Fiberが完了した場合は、Fiber内のクロージャの最終的な戻り値が返されます。

サンプルコードでは、まずFiberオブジェクトを生成しています。Fiberのクロージャ内では、Fiber::suspend()を使用してFiberを中断し、文字列"Hello, "を返しています。次に、$fiber->start("World")でFiberを開始し、最初のFiber::suspend()まで実行します。$fiber->start()に渡した"World"は、Fiberのクロージャの引数$nameに渡されます。この時点でFiberは中断され、$resultには"Hello, "が格納されます。

その後、$fiber->resume("Goodbye, ")を呼び出すことでFiberが再開されます。Fiber::resume()に渡した"Goodbye, "は、Fiber::suspend()の戻り値としてFiber内の$greeting変数に格納されます。Fiberは中断された箇所から処理を再開し、"Goodbye, "と"World"を連結して、最終的な戻り値"Goodbye, World!"を返します。この戻り値は$finalResultに格納され、最後に表示されます。Fiber::resume()を使うことで、Fiberの状態を制御し、値をやり取りしながら処理を進めることが可能になります。

Fiber::resume()は、中断されたFiberを再開するメソッドです。引数$valueは、Fiber::suspend()によって中断された箇所に返される値となります。サンプルコードでは、Fiber内でsuspend()で中断された際に"Hello, "が返され、resume("Goodbye, ")でFiberを再開する際に"Goodbye, "がFiber内に渡されています。Fiberを開始するにはstart()を使用し、再開にはresume()を使用します。start()でFiberに引数を渡すことができ、resume()でsuspend()から値を返すことができます。Fiberが完了すると、resume()はFiberのreturn文で指定された値を返します。Fiberがすでに完了している場合、resume()を呼び出すとError例外が発生しますので注意が必要です。

PHP Fiber resume による履歴書解析処理

1<?php
2
3// これは履歴書解析の具体的なロジックではなく、
4// 複雑なタスク(例: 履歴書解析)をPHPのFiber機能を使って
5// 協調的に処理する仕組みを示すサンプルです。
6// Fiber::resume() は、中断されたFiberの実行を再開し、値を渡すために使用されます。
7// PHP 8.1 以降が必要です。
8
9/**
10 * 履歴書の各セクションを段階的に「解析」するFiberの処理を定義します。
11 * 実際にはここで外部ファイル読み込みや文字列処理などが行われますが、
12 * サンプルではシンプルなメッセージ表示と値の受け渡しを行います。
13 *
14 * @param string $initialData Fiber開始時に渡される初期データ(ここではダミー)
15 * @return array 解析された結果(ここではダミー)
16 */
17$parserFiber = new Fiber(function (string $initialData): array {
18    echo "Fiber: 解析を開始します。初期データ: '{$initialData}'\n";
19    $parsedSections = [];
20
21    // --- セクション1: 個人情報の解析を模倣 ---
22    echo "Fiber: 個人情報セクションの解析を開始します...\n";
23    // 実際にはここでファイルからのデータ読み込みや正規表現マッチングなどを行うと想定
24    $personalInfo = "ジョン・ドゥ, 1990/01/01";
25    $parsedSections['personal_info'] = $personalInfo;
26    echo "Fiber: 個人情報解析が完了しました。\n";
27
28    // 処理を一時中断し、メインスレッドに制御を戻します。
29    // Fiber::suspend() は、メインスレッドに値を返し、同時に次にメインスレッドから
30    // Fiber::resume() で渡される値を受け取る準備をします。
31    $nextInstruction = Fiber::suspend('個人情報セクションの処理が完了しました。');
32    echo "Fiber: メインスレッドから '{$nextInstruction}' を受け取りました。\n";
33
34    // --- セクション2: 職歴の解析を模倣 ---
35    echo "Fiber: 職歴セクションの解析を開始します...\n";
36    // メインスレッドから受け取った指示に基づいて処理を続行すると想定
37    if ($nextInstruction === '次の職歴データを解析') {
38        // 実際にはここでデータベースクエリやAPI呼び出しなどを行うと想定
39        $jobHistory = "ABC社 (2015-2020), XYZ社 (2020-現在)";
40        $parsedSections['job_history'] = $jobHistory;
41        echo "Fiber: 職歴解析が完了しました。\n";
42    }
43
44    // 再び処理を一時中断し、メインスレッドに制御を戻します。
45    $nextInstruction = Fiber::suspend('職歴セクションの処理が完了しました。');
46    echo "Fiber: メインスレッドから '{$nextInstruction}' を受け取りました。\n";
47
48    // --- セクション3: 学歴の解析を模倣 ---
49    echo "Fiber: 学歴セクションの解析を開始します...\n";
50    if ($nextInstruction === '次の学歴データを解析') {
51        $education = "大学 (2008-2012)";
52        $parsedSections['education'] = $education;
53        echo "Fiber: 学歴解析が完了しました。\n";
54    }
55
56    echo "Fiber: すべてのセクションの解析が完了しました。\n";
57    return $parsedSections; // 最終結果を返してFiberを終了します
58});
59
60echo "メインスレッド: Fiberを開始します。\n";
61// Fiber::start() を呼び出してFiberの実行を開始します。
62// Fiber内で最初の Fiber::suspend() まで実行され、その結果が返されます。
63$status = $parserFiber->start('ダミーの履歴書データ');
64echo "メインスレッド: Fiberから '{$status}' を受け取りました。\n";
65
66// Fiberが中断されているか確認
67if ($parserFiber->isSuspended()) {
68    echo "メインスレッド: Fiberが中断されています。職歴解析を再開します。\n";
69    // Fiber::resume() を呼び出して、中断されたFiberの実行を再開します。
70    // '次の職歴データを解析' という文字列をFiberに渡し、Fiberはこれを受け取って処理を続行します。
71    $status = $parserFiber->resume('次の職歴データを解析');
72    echo "メインスレッド: Fiberから '{$status}' を受け取りました。\n";
73}
74
75// 再びFiberが中断されているか確認
76if ($parserFiber->isSuspended()) {
77    echo "メインスレッド: Fiberが中断されています。学歴解析を再開します。\n";
78    // 再度 Fiber::resume() を呼び出して、Fiberの実行を再開します。
79    // '次の学歴データを解析' という文字列をFiberに渡し、Fiberはこれを受け取って処理を続行します。
80    $status = $parserFiber->resume('次の学歴データを解析');
81    echo "メインスレッド: Fiberから最終結果を受け取りました。\n";
82}
83
84// Fiberが終了しているか確認
85if ($parserFiber->isTerminated()) {
86    echo "メインスレッド: Fiberは終了しました。\n";
87    // Fiber::getReturn() を使って、Fiberの最終的な戻り値を取得できます。
88    $finalResult = $parserFiber->getReturn();
89    echo "メインスレッド: 最終的な解析結果:\n";
90    print_r($finalResult);
91}
92
93echo "メインスレッド: プログラムが終了しました。\n";
94
95?>

PHPのFiberは、プログラムの実行を一時的に中断し、必要に応じて再開できる協調的な並行処理の機能です。Fiber::resume()メソッドは、Fiber::suspend()によって中断されたFiberの実行を再開するために使用されます。このメソッドの$value引数には、中断中のFiberに渡したい情報や指示を指定します。Fiber内部では、Fiber::suspend()が呼び出された場所で、この$valueが戻り値として受け取られ、その後の処理の判断に利用されます。

Fiber::resume()の戻り値は、Fiberが次にFiber::suspend()を呼び出した際に返される値、またはFiberがすべての処理を終えて終了した場合の最終的な戻り値です。サンプルコードでは、履歴書解析という一連の処理をFiberで実行しています。メインスレッドはFiber::resume('次の職歴データを解析')のように具体的な指示をFiberに渡し、Fiberはその指示を受け取って職歴解析を進めます。このように、重い処理を小分けにして、メインスレッドとの間で段階的に制御とデータをやり取りしながら実行する仕組みを実現できます。これにより、システムの応答性を保ちつつ、複雑なタスクを効率的に処理することが可能になります。

Fiber::resume()は、PHP 8.1以降で利用できる、中断されたFiberの実行を再開し、同時にFiberへ値を渡すためのメソッドです。初心者が特に注意すべき点は、メインスレッドとFiberの間で、resume()がFiberへ値を送り、Fiber::suspend()がメインスレッドへ値を返す、という双方向のやり取りを混同しないことです。resume()を呼び出す際は、必ずFiber::isSuspended()でFiberが中断状態にあることを確認し、実行時エラーを防ぐようにしてください。この機能は、ファイル読み込みやAPI通信といった時間のかかる処理を段階的に実行し、メインスレッドの応答性を保ちたい場合に非常に有効です。適切に状態を管理し、値の受け渡しを理解することで、複雑なタスクを協調的に処理する強力なツールとなります。

PHP Fiber resume 基本的な使い方

1<?php
2
3/**
4 * Fiber::resume() メソッドの基本的な使用例。
5 * PHPのFiber(ファイバー)は軽量コルーチン機能を提供し、
6 * 実行フローの一時停止(suspend)と再開(resume)を可能にします。
7 * このスクリプトは、メインプログラムとファイバーの間で値がどのように受け渡されるかを
8 * システムエンジニアを目指す初心者にも分かりやすく示します。
9 */
10
11// Fiberオブジェクトを生成します。
12// コンストラクタには、そのファイバー内で実行されるコードをクロージャとして定義します。
13$fiber = new Fiber(function (string $initialData): string {
14    echo "  [Fiber] 実行開始。メインから初期データを受信しました: '{$initialData}'\n";
15
16    // Fiber::suspend() を呼び出すと、ファイバーの実行が一時停止し、
17    // 引数に指定した値('Hello from Fiber...')がメインプログラムに返されます。
18    // 同時に、この suspend() の呼び出しの戻り値として、
19    // 後続の Fiber::resume() から渡される値を受け取ります。
20    echo "  [Fiber] 処理を一時停止し、メインに値を返します。\n";
21    $dataFromMain = Fiber::suspend('Hello from Fiber (suspended)!');
22
23    echo "  [Fiber] メインプログラムから再開され、データを受信しました: '{$dataFromMain}'\n";
24
25    // ファイバー内の残りの処理
26    $processedData = "PROCESSED: " . strtoupper($dataFromMain);
27    echo "  [Fiber] 最終処理を完了し、結果を返します: '{$processedData}'\n";
28
29    // ファイバーが正常に終了し、最終的な戻り値をメインプログラムに返します。
30    return $processedData;
31});
32
33echo "[メイン] ファイバーを開始します。\n";
34// Fiber::start() を呼び出すと、ファイバーの実行が開始されます。
35// 引数('Initial Data for Fiber')はファイバーのクロージャの引数として渡されます。
36// 戻り値は、ファイバー内で最初に Fiber::suspend() から返された値です。
37$responseFromFiber1 = $fiber->start('Initial Data for Fiber');
38echo "[メイン] ファイバーが一時停止しました。Fiberから受信したデータ: '{$responseFromFiber1}'\n";
39
40echo "[メイン] Fiber::resume() でファイバーを再開し、新しいデータを渡します。\n";
41// Fiber::resume() を呼び出すと、一時停止中のファイバーが再開されます。
42// 引数('Data from Main via resume')は、ファイバー内の Fiber::suspend() の戻り値として渡されます。
43// 戻り値は、ファイバーが終了したときの最終的な戻り値です。
44$finalResultFromFiber = $fiber->resume('Data from Main via resume');
45echo "[メイン] ファイバーが終了しました。Fiberから受信した最終結果: '{$finalResultFromFiber}'\n";
46
47// ファイバーが正常に終了したか確認します。
48echo "[メイン] ファイバーは終了しましたか? " . ($fiber->isTerminated() ? 'はい' : 'いいえ') . "\n";
49

PHP 8で導入されたFiber(ファイバー)は、非同期処理などを効率的に記述するための軽量コルーチン機能です。このサンプルコードは、メインプログラムとファイバーの間で、データの受け渡しや実行フローの一時停止・再開がどのように行われるかを示しています。

まず、new Fiber(...)で実行される処理(クロージャ)を定義し、ファイバーを準備します。$fiber->start('Initial Data for Fiber')を呼び出すと、ファイバーの実行が開始され、引数に指定したデータがファイバー側のクロージャの引数として渡されます。ファイバー内でFiber::suspend('Hello from Fiber (suspended)!');が呼び出されると、ファイバーの実行は一時停止し、suspend()の引数に指定された値がstart()の戻り値としてメインプログラムに返されます。

次に、メインプログラムは$fiber->resume('Data from Main via resume');を呼び出して、一時停止中のファイバーを再開します。ここでresume()の引数に指定された値は、ファイバー内でFiber::suspend()の呼び出しの「戻り値」としてファイバーに渡されます。これにより、メインプログラムからファイバーへデータを送り返すことができます。ファイバーは残りの処理を完了し、最終的な結果をreturnで返します。このファイバーからの最終的な戻り値が、resume()メソッドの戻り値としてメインプログラムに返されます。このように、resume()は一時停止中のファイバーを再開し、メインプログラムからデータを渡し、ファイバーからの最終結果を受け取る役割を果たします。

Fiber::resume()は、Fiber::suspend()で実行が一時停止したファイバーに対してのみ使用します。一時停止していない状態で呼び出すと、エラーが発生しますので注意してください。resume()の引数で渡した値は、ファイバー内のsuspend()呼び出しの戻り値としてファイバーに渡されます。一方、resume()自体の戻り値は、ファイバーが次にsuspend()で返した値か、ファイバーが完了した際の最終結果です。ファイバーは、このように明示的な指示によって実行を切り替える協調的マルチタスク機能であり、非同期処理とは異なる点をご理解ください。

関連コンテンツ

関連IT用語