In-depth understanding of the exception mechanism of PHP principles_PHP tutorial

WBOY
Release: 2016-07-21 15:34:05
Original
872 people have browsed it

What is the principle of PHP's exception mechanism?
What is the ZEND_HANDLE_EXCEPTION at the end of each independently executable op array in PHP used for?
Let's start with a question. Last week, blue5tar asked A question: "For the following code, onError is obviously executed, but onException is not executed, why?".

Copy code The code is as follows:

function onError($errCode, $errMesg, $errFile, $errLine) {
echo "Error Occurredn";
throw new Exception($errMesg);
}
function onException($e) {
echo $e->getMessage();
}
set_error_handler("onError");
set_exception_handler("onException");
/* I never name files after me, so this file does not exist*/
require("laruence.php");

Run result:
Copy code The code is as follows:

Error Occurred
PHP Fatal error: main(): Failed opening required 'laruence.php

First of all, we need to know that when Require contains a problem that cannot be found, it will throw two errors one after another,
Copy code The code is as follows:

WARNING: Thrown when PHP tries to open this file.
E_COMPILE_ERROR: Thrown after failure returns from the function that opens the file in PHP

And we know that set_error_handler cannot catch E_COMPILE_ERROR errors:
The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called.
So, in onError, only the first WARNING error can be caught, and why is the exception thrown in onError not caught by the default exception_handler?
That’s it Let’s talk about PHP’s exception mechanism.
Students who understand opcodes (students who have a deep understanding of PHP principles of Opcodes) know that before PHP5.3, the last item of each op array (file, function, method) that can be run independently The opcodes are all ZEND_HANDLE_EXCEPTION, and what is this opcode used for?
It turns out that in PHP, when an exception is thrown, it will jump to the last line of each op array to execute this ZEND_HANDLE_EXCEPTION, pseudo code As follows:
Copy code The code is as follows:

void on_throw_exception(zval *exception TSRMLS_DC) {
1. Determine whether An exception has been thrown
2. Record the exception
3. Record the serial number of the next op line to be executed
4. The serial number of the next op line to be executed = the last one of the current op array
}

Well, just like rewriting the ip register, rewriting the sequence number of the next op line to be executed changes the flow of the program. In this way, it will enter the processing logic of ZEND_HANDLE_EXCEPTION.
In ZEND_HANDLE_EXCEPTION, it will be judged whether the exception is in try catch,
Copy the code The code is as follows:

If If it is, set the next op line to be executed as the op line of the first catch, and continue execution.
If not, destroy some unnecessary variables and opline, and then directly end the execution process

Some students are asking: "When will the default exception handling function (user_exception_handler) set by set_exception_handler take effect?"
Well, it is determined whether there is a default exception after the execution is completed and the LOOP is exited. Processing function, if called only:
Copy code The code is as follows:

//Execute
zend_execute(EG( active_op_array) TSRMLS_CC);
if (EG(exception)) {
if (EG(user_exception_handler)) {
Call user-defined default exception handler function
} else {
Uncaught Exception
}
} else {
No exception
}
destroy_op_array(EG(active_op_array) TSRMLS_CC);
efree(EG(active_op_array));

In-depth understanding of the exception mechanism of PHP principles_PHP tutorial
PHP exception process

Note: There is an imprecision in the picture, that is, when determining whether it is the last catch block, (is_a) will be judged at the same time, and if it is, it will enter the last A catch block is executed.
When PHP encounters a Fatal Error, it will directly zend_bailout, and zend_bailout will cause the program flow to directly skip the above code segment, which can also be understood as direct exit (longjmp), which leads to user_exception_handler has no chance to work.
After knowing this, I think the reason for the question at the beginning of the article is very clear, right?
Finally, regarding ZEND_HANDLE_EXCEPTION, some students may have questions: If so, then why Does every independently executable op array have this ZEND_HANDLE_EXCEPTION at the end? The simplest thing is, if a function does not throw, then this opcode is obviously unnecessary? Hehe, you are very smart. Starting from PHP 5.3, I have followed your instructions The idea has been adjusted. Only at the throw moment, the ZEND_HANDLE_EXCEPTION opline will be dynamically generated.
PHP5 changelog:
Changed exception handling. Now each op_array doesn't contain ZEND_HANDLE_EXCEPTION opcode in the end. (Dmitry)

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/322464.htmlTechArticleWhat is the principle of PHP’s exception mechanism? The ZEND_HANDLE_EXCEPTION at the end of each independently executable op array in PHP is used What are you here for? Let’s start with a question. Last week,...
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!