php5に例外が発生し、その後常に例外をスローするZendFrameworkが表示されたとき、理解できませんでした:なぜ例外がお気に入りのtrigger_error()よりも優れているのでしょうか? 私は長い間考え、同僚と話し合い、この問題を見つけました。 これで、trigger_error()を使用する場所と、新しい例外()をスローする場所が明確にわかりました。
2つの基本的な違いは何ですか?
間違い
エラーは修正できないものであり、報告できるのはログへの書き込み、開発者へのメール送信、ユーザーへの謝罪のみです。 たとえば、エンジンがデータベースに接続できない場合、これはエラーです。 それだけです ポイント。 このサイトはデータベースなしでは機能せず、私はそれについて何もできません。 したがって、ales_kaput()およびtrigger_error()を呼び出すと、errorHandlerから電子メールが送信され、訪問者に「ごめん、サイトがダウンしています」というメッセージが表示されます。
例外
例外は間違いではなく、何らかの形で処理する必要がある特別な状況です。 たとえば、電卓でゼロで除算しようとすると、電卓はフリーズせず、開発者にメッセージを送信せず、謝罪します。 このような状況は、通常のifで処理できます。 厳密に言えば、 例外は、実行のフローを制御できる言語構造です 。 これは、if、for、およびreturnと同等の構造です。 それだけです。 このメカニズムはこれ以上のものではありません。 フロー制御のみ。
主な目的は、カスケードに沿って転送することです。 これを例で示します。カスケードで相互に呼び出す3つの関数があります。
<?php a(); function a() { b(); } function b() { c(99); } function c($x) { if ($x === 0) { // , // c() b(), // a() } return 100 / $x; }
この問題は、例外メカニズムなしで解決できます。 たとえば、すべての関数に特別な型を強制的に返すことができます(経験豊富なpahapashnikの場合、PEAR_Errorを覚えておく必要があります) 。 簡単にするために、nullを使用します。
<?php a(); function a() { echo 'a-begin'; $result = b(); if ($result === null) { echo ' '; return; } echo 'a-stop'; } function b() { echo 'b-begin'; $result = c(0); if ($result === null) { return null; } echo 'b-stop'; return true; } function c($x) { echo 'c-begin'; if ($x === 0) { return null; } echo 'c-stop'; return 100 / $x; }
仕事の結果:
はじめに
b-begin
c-begin
ゼロ除算は良くありません
タスクは完了しましたが、カスケードの上位の従属関数の作業結果をスローするように、中間関数b()を変更する必要がありました。 そして、5つまたは10の機能のカスケードがある場合はどうなりますか? 次に、すべての中間機能を変更する必要があります。 そして、例外がコンストラクターにある場合はどうなりますか? 松葉杖を代用しなければならないこと。
そして今、例外を使用したソリューション:
a(); function a() { echo 'a-begin'; try { b(); echo 'a-stop'; } catch (Exception $e) { echo $e->getMessage(); } } function b() { echo 'b-begin'; c(0); echo 'b-stop'; } function c($x) { echo 'c-begin'; if ($x === 0) { throw new Exception(' '); } echo 'c-stop'; return 100 / $x; }
実行結果は同じになります。 関数b()は元の形のままで、そのままです。 これは、カスケードが長い場合に特に当てはまります。 また、$ eオブジェクトには、状況に関する追加情報が含まれる場合があります。
したがって、エラーと例外は、まったく異なる問題を解決するためのまったく異なるツールであることがわかります。
エラーは取り返しのつかない状況です。
例外-機能のカスケードを中断し、いくつかの情報を転送できます。 グローバルなreturnステートメントのようなもの。 カスケードがない場合は、ifまたはreturnを使用するだけです。
エラーは必ずしもエラーではありません
「Zend Frameworkを見てください-常に例外をスローします。 これらは最高の実践であり、同様に行う必要があります。 データベースに接続できなかった場合でも、例外をスローする必要があります。
この記事では、この誤解を払拭したいだけです。 Zendは本当に最高の実践的手法ですが、Zendのプログラマーは別のボートに乗って他のことをしています。 彼らと私との根本的な違いは、多くのプロジェクトで使用されるユニバーサルライブラリを書くことです。 そして、彼らは鐘楼から何が重大な間違いであり、何が修正可能であるかを言うことができません。
たとえば、プロジェクトに複数のMySQLサーバーがあり、そのうちの1つがクラッシュしたときにそれらを切り替えることができます。 したがって、ユニバーサルライブラリとしてのZend_Dbは例外をスローし、それをどう処理するかを自分で決定します。 例外は柔軟です-どのレベルでどのような状況をキャッチするかを決定します。 エラーメッセージを表示するか、方法がわかっている場合は状況を修正してください。 ユニバーサルライブラリを記述するときは、常にexceptionsをスローする必要があります。 これにより、ライブラリがより柔軟になります。
その結果、両方のメカニズムには独自の特性があり、最も重要なことは、独自の運命があり、これらの宛先がまったく交差していないことです。
PHPでは、エラー処理メカニズムが長い間開発されてきましたが、これは非常に効果的です。 必要な場所でうまく使います。