LoginSignup
18
11

More than 5 years have passed since last update.

[PHP] try-catch-finally句内のreturnについて

Last updated at Posted at 2019-01-26

概要

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が勝つ。まさに例外の握りつぶし。(コメントより)

18
11
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
11