PHPエラー処理:die()とtrigger_error()と例外のスロー


119

PHPのエラー処理に関して-私の知る限り、3つのスタイルがあります。

  1. die()またはexit()スタイル:

    $con = mysql_connect("localhost","root","password");
    
    if (!$con) {
     die('Could not connect: ' . mysql_error());
    }
  2. throw Exception スタイル:

     if (!function_exists('curl_init')) {
    
          throw new Exception('need the CURL PHP extension. 
                               Recomplie PHP with curl');
        }
  3. trigger_error() スタイル:

    if(!is_array($config) && isset($config)) {
            trigger_error('Error: config is not an array or is not set', E_USER_ERROR);
        }

現在、PHPマニュアルでは3つの方法すべてが使用されています。

  • 私が知りたいのは、どのスタイルを選ぶべきか、そしてその理由は何ですか?

  • これらの3つのドロップインの交換品は交換可能ですか?

少しOT:PHPのエラー処理オプションがphp開発者を混乱させるほど多すぎると私だけが思うのですか、それとも誰もが思うのですか?


4
これらは「スタイル」ではありません。それらは異なる言語機能です。さまざまな目的で。
マリオ2011

11
@mario:字下げされた目的は何ですか?私を啓発してください:)
CuriousMind

あなたは質問を素晴らしい方法で説明しました。お問い合わせいただきありがとう
ございます

回答:


86

最初のものはエンドユーザーに関係のない情報を転送するため、本番用コードでは決して使用しないでください(ユーザーは「データベースに接続できません」について何もできません)。

特定の重要なコードポイントでアプリケーションが失敗する可能性があり、コードを複数の呼び出しレベルにわたって回復させたい場合は、例外をスローします。

trigger_error()では、さまざまなレベルのエラーメッセージを使用して詳細なエラーレポートを作成し、それらのエラーをエンドユーザーから(を使用してset_error_handler())非表示にして、テスト中に表示することができます。

またtrigger_error()、カスタムエラーハンドラーを使用してプロダクションコードで抑制できる、開発中に重要な致命的でないメッセージを生成することもできます。致命的なエラーも発生する可能性があります(E_USER_ERROR)が、回復できません。それらの1つをトリガーすると、プログラムの実行その時点で停止します。これが、致命的なエラーの場合は例外を使用する必要がある理由です。このようにして、プログラムのフローをより詳細に制御できます。

// Example (pseudo-code for db queries):

$db->query('START TRANSACTION');

try {
    while ($row = gather_data()) {
       $db->query('INSERT INTO `table` (`foo`,`bar`) VALUES(?,?)', ...);
    }
    $db->query('COMMIT');
} catch(Exception $e) {
    $db->query('ROLLBACK');
}

ここで、gather_data()E_USER_ERRORやを使用してdie())単純に不法INSERT侵入した場合、可能性があれば、以前のステートメントはそれがデータベースに組み込まれているはずです。


2
trigger_error()例外のうち、例外をスローする:どれをいつ使用するべきですか?
CuriousMind 2011

@Gaurishその上に追加された例を参照してください。
Linus Kleen、2011

2
あなたの例を読んだ後、私は今例外のスローの背後にある目的をよりよく理解していると思います。ありがとう:)
CuriousMind

1
@Pacerier実際には、サーバーの構成によって異なります。システム、デフォルトで自動コミットするように構成されている可能性があるため、明示的ROLLBACKです。この疑似コードの例は、自動コミットするように構成されていない(COMMITステートメントが必要です)サーバーとそうするサーバーの両方のケースをカバーしています。
Linus

1
@LinusKleen、ラインを実行すると、自動コミットがオフになりませんquery('START TRANSACTION');か?
パチェリエ2013

10

私は通常、開発コードで簡単なデバッグを行うための最初の方法を使用します。生産にはお勧めできません。最善の方法は、例外をスローすることです。これは、プログラムの他の部分でキャッチして、エラー処理を行うことができます。

3つのスタイルは、相互のドロップイン置換ではありません。1つ目はエラーではなく、スクリプトを停止してデバッグ情報を出力し、手動で解析できるようにするためのものです。2番目はそれ自体はエラーではありませんが、キャッチしないとエラーに変換されます。最後の1つは、PHPエンジンの実際のエラーを引き起こし、PHP環境の構成に従って処理されます(場合によってはユーザーに表示されることもあれば、単にファイルに記録されるか、まったく保存されないこともあります)。


1
例外がスローされてもキャッチされない場合はどうなりますか?致命的なエラーが発生すると思います。そして、trigger_error()同じことが起こります。違いは何ですか?
CuriousMind 2011

4
違いは、例外をキャッチして、好きな方法で処理できることです。
EmilVikström11年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.