【PHP8.x】throwメソッドの使い方

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

作成日: 更新日:

基本的な使い方

『throwメソッドは、中断されているファイバーに例外をスローし、実行を再開させるメソッドです』 このメソッドは、Fiber::suspend()の呼び出しによって一時停止しているファイバーに対して使用されます。引数には、スローしたいThrowableインターフェースを実装したオブジェクトを指定します。throwメソッドが呼び出されると、ファイバーの実行はFiber::suspend()が呼び出された箇所から再開されますが、その際、Fiber::suspend()の式が指定された例外をスローしたかのように振る舞います。これにより、ファイバーの外部から内部の処理に対して意図的にエラーを発生させ、try...catchブロックなどで定義された例外処理フローを強制的に開始させることが可能になります。ファイバーが次に中断するか正常に終了した場合、throwメソッドはその結果の値を返します。もし、ファイバー内部でこの例外が捕捉されずにファイバーが終了した場合、その例外はthrowメソッドの呼び出し元で再びスローされ、呼び出し元のコンテキストで処理する必要があります。

構文(syntax)

1<?php
2
3$fiber = new Fiber(function (): void {
4    try {
5        // ファイバーの実行を中断し、外部からの再開を待つ
6        Fiber::suspend();
7    } catch (Exception $e) {
8        // throw() メソッドによって渡された例外をここでキャッチする
9        echo "ファイバー内でキャッチした例外: " . $e->getMessage();
10    }
11});
12
13// ファイバーを開始し、最初の Fiber::suspend() まで実行する
14$fiber->start();
15
16// 構文: $fiber->throw($exception);
17// 実行が中断されているファイバーに例外をスローして再開させる
18if ($fiber->isSuspended()) {
19    $fiber->throw(new Exception('これは外部からスローされた例外です'));
20}
21
22?>

引数(parameters)

Throwable $exception

  • Throwable $exception: Fiber内で発生した例外オブジェクト

戻り値(return)

mixed

Fiber::throw() メソッドは、Fiber の実行を中断した地点で例外を投げます。このメソッドの戻り値は、Fiber が再開された際に、Fiber::resume() メソッドに渡される値、または Fiber が例外を投げた場合にその例外オブジェクトです。

サンプルコード

Fiber::throw()で例外を発生させる

1<?php
2
3/**
4 * Fiber::throw() の使用例
5 */
6
7class MyException extends Exception {}
8
9function createFiber(): Fiber
10{
11    return new Fiber(function (): void {
12        try {
13            Fiber::suspend();
14        } catch (MyException $e) {
15            echo "キャッチした例外: " . $e->getMessage() . PHP_EOL;
16        }
17    });
18}
19
20$fiber = createFiber();
21
22$fiber->start(); // Fiberを開始
23
24try {
25    $fiber->throw(new MyException("Fiber内で例外を発生させます")); // Fiber内で例外を発生させる
26} catch (Throwable $e) {
27    echo "Fiber::throw()で例外発生" . PHP_EOL;
28}

このサンプルコードは、PHP 8のFiberクラスにおけるthrowメソッドの使い方を示しています。Fiber::throw()は、ファイバー(軽量スレッドのようなもの)の実行を中断し、指定された例外をファイバー内部で発生させるために使用されます。

まず、MyExceptionというカスタム例外クラスを定義しています。次に、createFiber()関数で、新しいFiberインスタンスを作成し、その中でFiber::suspend()を呼び出してファイバーを一時停止させています。try-catchブロックでMyExceptionをキャッチし、例外メッセージを出力するようにしています。

メインの処理では、createFiber()で作成したファイバーを$fiber->start()で開始します。そして、$fiber->throw(new MyException("Fiber内で例外を発生させます"))を呼び出すことで、ファイバー内部でMyExceptionを発生させています。throwメソッドには、Throwableインターフェースを実装した例外オブジェクトを引数として渡します。

この例外は、ファイバー内部のtry-catchブロックでキャッチされ、例外メッセージが出力されます。さらに、Fiber::throw()自体も例外を発生させる可能性があるため、外側のtry-catchブロックでThrowableをキャッチしています。このように、Fiber::throw()を使用することで、ファイバーの実行フローを制御し、例外処理を行うことができます。Fiber::throw()メソッドは戻り値としてmixed型を返しますが、例外がスローされた場合は処理が中断されるため、通常は戻り値は利用されません。

Fiber::throw()は、中断中のファイバー内で例外を発生させるメソッドです。ファイバー内で例外が発生すると、Fiber::suspend()呼び出し箇所まで処理が巻き戻り、そこで例外がキャッチされます。サンプルコードでは、MyExceptionをスローしていますが、Throwableを継承した例外であればスロー可能です。

注意点として、Fiber::throw()を呼び出す前に、ファイバーがFiber::start()またはFiber::resume()で開始されている必要があります。また、ファイバー内で例外がキャッチされない場合、例外はファイバーを呼び出した側のスコープに伝播します。サンプルコードでは、try-catchブロックで例外を捕捉していますが、捕捉しない場合は予期しないエラーが発生する可能性があります。

【PHP8.x】throwメソッドの使い方 | いっしー@Webエンジニア