概要
try-catch-finally句内のreturnについて - @eijenson さん の記事を読んで、PHPではどうなってんだろ?という素朴な疑問が湧いたので、試して見た。
前提環境
macOS High Sierra 10.13.6
PHP 7.3.0 (cli) (built: Dec 7 2018 11:06:29) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.0-dev, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.3.0, Copyright (c) 1999-2018, by Zend Technologies
結果
ソースコード
<?php
class Sample {
public function returnsample()
{
try {
echo 'try!';
throw new Exception('sample!');
return 'try!!!';
} catch (Exception $e) {
echo 'catch!';
echo $e;
return 'catch';
} finally {
echo 'finally statement is executed!';
return 'Crush the exeception';
}
}
}
$a = new Sample();
$sample = $a->returnsample();
// ちゃんと例外 catch してるので、これ以下の箇所について実行されるのが自然
// @sj-i さんのコメントでの指摘より
echo "\n\nsample output!\n";
echo $sample;
出力結果
$ php try-catch-return.php
try!catch!Exception: sample! in /Users/oki.suguru/workspace/php/try-catch-return.php:17
Stack trace:
#0 /Users/oki.suguru/workspace/php/try-catch-return.php(33): Sample->returnsample()
#1 {main}finally statement is executed!
sample output!
Crush the exeception%
見事に $e の中身である $eが 握りつぶされることがわかった。
Javaと同様,PHPでもfinally句のなかで、returnすると、例外の内容が握りつぶされるようだ。
バージョンごとに何か違いがあるかどうかは未検証。
気が向いたらやることにする。
以下 @sj-i さんのコメントでの指摘より追記
例外を catch して返り値に直して呼び出し元からエラー検知するような場合、catch からの返り値が潰され、例外発生しなくても実行される finally からの返り値が反映される。
catch からの return がデッドコードになる (コメントより)
じゃあ、さらにcatchを無くしたらどうなっちゃうのか @crhg さんのコメントより
catchがないときの返り値
<?php
class Sample {
public function returnsample()
{
try {
echo 'try!';
throw new Exception('sample!');
return 'try!!!';
} finally {
echo 'finally statement is executed!';
return 'Crush the exeception';
}
}
}
$a = new Sample();
$sample = $a->returnsample();
echo "\n\nsample output!\n";
echo $sample;
出力結果
try!finally statement is executed!
sample output!
Crush the exeception
例外よりfinallyの中のreturnが勝つ。まさに例外の握りつぶし。(コメントより)