こんにちは。よっしーです(^^)
今日は、PHPのErrorsについてご紹介します。
背景
PHP8.2を利用したAPIを開発しているときにErrorsを利用したので、そのときの調査内容を備忘としてのこしました。
こちらのサイトを参考にしています。
例外のサンプル1
<?php
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
return 1/$x;
}
try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
// Continue execution
echo "Hello World\n";
このPHPコードは例外の使用例を示しています。以下はコードの概要です。
inverse($x)
関数は引数$x
を受け取り、$x
がゼロである場合に例外をスローし、それ以外の場合に1/$x
の結果を返します。try
ブロック内で、inverse(5)
が呼び出されて5
の逆数が表示され、次にinverse(0)
が呼び出されて例外がスローされます。- 例外がスローされると、
catch (Exception $e)
ブロックが実行され、その例外が捕捉されます。このブロック内で例外のメッセージが表示されます。 - 最後に、
echo "Hello World\n";
が実行され、プログラムは継続します。
このコードの出力は次のようになります:
0.2
Caught exception: Division by zero.
Hello World
最初に inverse(5)
の結果が表示され、次にゼロでの割り算が試みられ、例外がスローされて “Caught exception: Division by zero.” が表示され、最後に “Hello World” が表示されます。
例外のサンプル2
<?php
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
return 1/$x;
}
try {
echo inverse(5) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
} finally {
echo "First finally.\n";
}
try {
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
} finally {
echo "Second finally.\n";
}
// Continue execution
echo "Hello World\n";
このPHPコードは、try
, catch
, および finally
ブロックを使用して例外処理を示しています。以下はコードの概要です。
inverse($x)
関数は引数$x
を受け取り、$x
がゼロである場合に例外をスローし、それ以外の場合に1/$x
の結果を返します。- 最初の
try
ブロック内で、inverse(5)
が呼び出されて5
の逆数が表示されます。catch (Exception $e)
ブロックが定義されており、例外がスローされた場合に捕捉します。この場合、例外はスローされません。 finally
ブロックが実行されて “First finally.” が表示されます。- 次に、2番目の
try
ブロックが開始され、inverse(0)
が呼び出されてゼロでの割り算が試みられ、例外がスローされます。 - 2番目の
catch (Exception $e)
ブロックが実行され、例外のメッセージが表示されます。 - 2番目の
finally
ブロックが実行されて “Second finally.” が表示されます。 - 最後に、
echo "Hello World\n";
が実行され、プログラムは継続します。
このコードの出力は次のようになります:
0.2
First finally.
Caught exception: Division by zero.
Second finally.
Hello World
最初に inverse(5)
の結果と “First finally.” が表示され、次にゼロでの割り算が試みられ、例外がスローされ、”Caught exception: Division by zero.” と “Second finally.” が表示され、最後に “Hello World” が表示されます。
例外のサンプル3
<?php
function test() {
try {
throw new Exception('foo');
} catch (Exception $e) {
return 'catch';
} finally {
return 'finally';
}
}
echo test();
このPHPコードは、try
, catch
, および finally
ブロックを使用して、test()
関数内で例外処理を示しています。以下はコードの動作の概要です。
test()
関数内で、try
ブロックが開始され、その中でthrow new Exception('foo');
によって例外がスローされます。catch (Exception $e)
ブロックが定義されており、このブロックはスローされた例外を捕捉します。この場合、例外オブジェクトが$e
に割り当てられ、このブロック内のコードが実行されます。このブロックは文字列 ‘catch’ を返します。- その後、
finally
ブロックが実行されます。このブロックは文字列 ‘finally’ を返します。 test()
関数は ‘catch’ ではなく ‘finally’ を返します。echo test();
が呼び出され、test()
関数の結果である ‘finally’ が表示されます。
したがって、このコードの出力は ‘finally’ です。finally
ブロックの内容が最終的に返され、catch
ブロック内で返された値は無視されます。
例外のサンプル4
<?php
class MyException extends Exception { }
class Test {
public function testing() {
try {
try {
throw new MyException('foo!');
} catch (MyException $e) {
// rethrow it
throw $e;
}
} catch (Exception $e) {
var_dump($e->getMessage());
}
}
}
$foo = new Test;
$foo->testing();
このPHPコードは、ネストされた例外処理の使用例を示しています。以下はコードの動作の概要です。
MyException
クラスはException
クラスを継承しています。これはカスタム例外クラスです。Test
クラスにはtesting()
メソッドがあり、このメソッド内で例外処理が行われています。- 最初の
try
ブロック内で、try
ブロックがネストされています。内部のtry
ブロックでthrow new MyException('foo!');
によってMyException
例外がスローされます。 - その内部の
catch (MyException $e)
ブロック内で、捕捉されたMyException
例外が再度スローされます。 - 外側の
catch (Exception $e)
ブロック内で、この再度スローされた例外が捕捉され、そのメッセージがvar_dump($e->getMessage());
によって表示されます。
したがって、このコードの出力は MyException
例外のメッセージ “foo!” です。外側の catch
ブロックが内側の catch
ブロックで再度スローされた例外を捕捉しています。
例外のサンプル5
<?php
class MyException extends Exception { }
class MyOtherException extends Exception { }
class Test {
public function testing() {
try {
throw new MyException();
} catch (MyException | MyOtherException $e) {
var_dump(get_class($e));
}
}
}
$foo = new Test;
$foo->testing();
このPHPコードは、catch
ブロック内で複数の例外型を処理する方法を示しています。以下はコードの動作の概要です。
MyException
クラスとMyOtherException
クラスはどちらもException
クラスを継承しています。これらはカスタム例外クラスです。Test
クラスにはtesting()
メソッドがあり、このメソッド内で例外処理が行われています。try
ブロック内で、throw new MyException();
によってMyException
例外がスローされます。catch (MyException | MyOtherException $e)
ブロック内で、捕捉された例外がMyException
またはMyOtherException
のいずれかである場合にその例外のクラス名を表示します。このように、複数の例外型を同じcatch
ブロックで処理できます。
したがって、このコードの出力は MyException
例外のクラス名 “MyException” です。外部でスローされた MyException
例外が catch
ブロックで捕捉され、その例外の型を確認します。
例外のサンプル6
<?php
class SpecificException extends Exception {}
function test() {
throw new SpecificException('Oopsie');
}
try {
test();
} catch (SpecificException) {
print "A SpecificException was thrown, but we don't care about the details.";
}
このPHPコードは、PHP 8以降で導入された新しい例外ハンドリング構文を示しています。以下はコードの動作の概要です。
SpecificException
クラスはException
クラスを継承しています。これはカスタムの例外クラスです。test()
関数内で、throw new SpecificException('Oopsie');
によってSpecificException
例外がスローされます。try
ブロック内でtest()
関数が呼び出されます。catch (SpecificException)
ブロック内では、SpecificException
がスローされた場合にその例外を捕捉し、詳細には関心がないことを示すメッセージが表示されます。この新しいcatch
構文では、例外型だけで例外をキャッチでき、例外の変数を明示的に宣言する必要はありません。
このコードは、SpecificException
がスローされ、それが catch
ブロックで捕捉され、指定のメッセージが表示されます。この新しい構文は、特定の例外型に興味があり、詳細情報は不要な場合に便利です。
例外のサンプル7
<?php
function test() {
do_something_risky() or throw new Exception('It did not work');
}
try {
test();
} catch (Exception $e) {
print $e->getMessage();
}
このPHPコードは、do_something_risky()
関数が失敗した場合に例外をスローする例を示しています。以下はコードの動作の概要です。
test()
関数内で、do_something_risky()
関数が呼び出されます。この関数は何らかのリスクのある処理を実行し、その結果が成功したかどうかを返すものと仮定します。do_something_risky()
関数が成功しない場合、or
の右側の式が評価されます。この右側の式はthrow new Exception('It did not work');
で、Exception
例外がスローされます。try
ブロック内でtest()
関数が呼び出されます。catch (Exception $e)
ブロック内では、Exception
例外が捕捉され、その例外のメッセージが表示されます。
したがって、このコードの出力は “It did not work” です。do_something_risky()
関数が失敗し、例外がスローされ、そのメッセージが catch
ブロックで表示されます。この方法を使用することで、特定の条件が満たされない場合に例外をスローすることができます。
おわりに
今日は、PHPのErrorsについてご紹介しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント