ホームページ  >  記事  >  バックエンド開発  >  PHP 原則の例外メカニズムを深く理解する_PHP チュートリアル

PHP 原則の例外メカニズムを深く理解する_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-21 15:34:05873ブラウズ

PHP の例外メカニズムの原理は何ですか?
PHP で個別に実行可能な op 配列の最後にある ZEND_HANDLE_EXCEPTION は何に使用されますか?
先週、blue5tar が質問をしました。は明らかに実行されますが、onException は実行されません。なぜですか?」 errLine) {
echo "エラーが発生しました";

新しい例外をスロー($errMesg) } 関数 onException($e) { echo $e->getMessage() }
set_error_handler("onError" );
set_Exception_handler("onException");
/* 私はファイルに自分の名前を付けたことがないので、このファイルは存在しません*/
require("laruence.php");



コードをコピーします

コードは次のとおりです:


エラーが発生しました
PHP 致命的なエラー: main(): 必要な 'laruence.php を開くことができませんでした

まず、Require に見つからない問題が含まれている場合、前後に 2 つのエラーがスローされます。
コードをコピー コードは次のとおりです:

警告: PHP がこのファイルを開こうとするとスローされます。
E_COMPILE_ERROR: ファイルを開く関数からエラーが返された後にスローされます。 PHP のファイル

そして、set_error_handler は E_COMPILE_ERROR エラーをキャッチできないことがわかっています:
次のエラー タイプは、ユーザー定義関数では処理できません: E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING、およびファイル内で発生する E_STRICT のほとんどset_error_handler() が呼び出される場所
それでは、onError では最初の WARNING エラーのみがキャッチされますが、なぜ onError でスローされた例外はデフォルトの例外ハンドラではキャッチされないのでしょうか? これは PHP の例外メカニズムについてです。オペコード (PHP の原則とオペコードを深く理解している人) は、PHP5.3 より前では、独立して実行できる各オペ配列 (ファイル、関数、メソッド) の最後のオペコードが ZEND_HANDLE_EXCEPTION であり、このオペコードが何を行うかを知っています。 PHP では、例外がスローされると、この ZEND_HANDLE_EXCEPTION を実行するために各 op 配列の最後の行にジャンプすることがわかりました。疑似コードは次のとおりです:
コードをコピーします。
コードは次のとおりです:

void on_throw_Exception(zval *Exception TSRMLS_DC) {
1. 例外がスローされたかどうかを確認します
2. 実行される次の op 行のシーケンス番号を記録します。
4. 次に実行される op 行のシリアル番号 = 現在の op 配列の最後のもの
}


さて、IP レジスタを書き換えるのと同じように、次に実行される op 行のシリアル番号を書き換えるとフローが変わります。このようにして、プログラムのZEND_HANDLE_EXCEPTIONの処理に入ります
ZEND_HANDLE_EXCEPTIONでは、try catch内に例外があるかどうかを判断します コードは以下の通りです。 :

そうであれば、最初の op 行をキャッチして次の op 行を実行するように設定し、実行を続行します。
そうでない場合は、いくつかの不要な変数と opline を破棄し、実行プロセスを直接終了します


いくつか。学生は「set_Exception_handler で設定したデフォルトの例外処理関数 (user_Exception_handler) はいつ有効になりますか?」と聞きたいです。
そうですね、デフォルトの例外処理関数があるかどうかは、実行が完了して LOOP が終了した後に判断されます。存在する場合は、それが呼び出されます:


コードをコピーします
コードは次のとおりです: //Execute zend_execute(EG(active_op_array) TSRMLS_CC); {
if (EG(user_Exception_handler)) {
ユーザー定義のデフォルト例外ハンドラー関数を呼び出す
} else {
キャッチされない例外
}
} else {
例外なし
}
destroy_op_array(EG(active_op_array) TSRMLS_CC); EG(active_op_array));
PHP 原則の例外メカニズムを深く理解する_PHP チュートリアル
PHP例外処理

注: 画像に不正確があります。つまり、最後のcatchブロックであるかどうかを判断する際に、(is_a)も同時に判断され、そうである場合は入ります。
PHP で致命的なエラーが発生すると、zend_bailout が直接実行され、プログラム フローが上記のコード セグメントを直接スキップします。これは直接終了 (longjmp) とも解釈できます。その結果、 user_Exception_handler は有効になりません。
これを理解して、記事の冒頭の質問の理由を考えてみましょう。
最後に、ZEND_HANDLE_EXCEPTION について、次のような疑問を持つ人もいるでしょう。この場合、独立して実行可能なすべての op 配列がこの ZEND_HANDLE_EXCEPTION になるのはなぜでしょうか? 最後に、単純に、関数がスローされない場合、このオペコードは明らかに不要です。あなたのアイデアに従って...スローの瞬間にのみ、ZEND_HANDLE_EXCEPTION opline が動的に生成されます。
PHP5 変更ログ:
各 op_array には最終的に ZEND_HANDLE_EXCEPTION オペコードが含まれなくなりました。

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/322464.html技術記事 PHP の例外メカニズムの原理は何ですか? PHP で個別に実行可能な op 配列の最後にある ZEND_HANDLE_EXCEPTION は何に使用されますか? 先週、...
という質問から始めましょう。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。