In-depth analysis of the abnormal mechanism of PHP principles

Source: Internet
Author: User

What is the principle of the PHP exception mechanism?

What is the zend_handle_exception at the end of each op array that can be executed independently in PHP?

Let's start with a question. Last week, blue5tar raised the following question:CodeOnerror is clearly executed, but onexception is not executed. Why ?".

Copy code The Code is as follows: <? PHP
Function onerror ($ errcode, $ errmesg, $ errfile, $ errline ){
Echo "error occurred \ n ";
Throw new exception ($ errmesg );
}

Function onexception ($ e ){
Echo $ e-> getmessage ();
}

Set_error_handler ("onerror ");

Set_exception_handler ("onexception ");

/* I will never name the file with my name, so this file does not exist */
Require ("laruence. php ");

Running result:Copy codeThe Code is as follows: Error occurred
PHP fatal error: Main (): Failed opening required' laruence. php

First, we need to know that when require contains a problem that cannot be found, two errors will be thrown before and after require,Copy codeThe Code is as follows: 1. Warning: thrown when PHP tries to open this file.
2. e_compile_error: thrown after the function of opening the file from php fails to return

As we know, set_error_handler cannot catch e_compile_error:

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 found () is called.

Therefore, in onerror, only the first warning error can be caught, but the exception thrown in onerror is not caught by the default exception_handler?

Let's talk about the abnormal mechanism of PHP.

Everyone familiar with Opcode (Opcodes, who has a deep understanding of PHP principles, knows that before php5.3, the last opcode of every Independently Running op array (file, function, method) was zend_handle_exception, what is the opcode used?

In PHP, when an exception is throw, it will jump to the last line of each op array to execute this zend_handle_exception. The pseudo code is as follows:Copy codeCode: void on_throw_exception (zval * exception tsrmls_dc ){
1. determine whether an exception has been thrown
2. Record exception
3. Record the sequence number of the next op line to be executed
4. The next op line number to be executed = the last one of the current op Array
}

Well, just like the IP address register, rewrite the serial number of the next op line to be executed and change it.ProgramIn this way, it enters the processing logic of zend_handle_exception.

In zend_handle_exception, it determines whether the exception is in try catch,

Copy code The Code is as follows: if yes, set the next op line to be executed as the op line of the first catch and continue the execution.
If not, destroy unnecessary variables and opline and directly end the execution process.

Some may ask: "When will the default processing function (user_exception_handler) take effect for the exception set by set_exception_handler ?"

Well, it is only after the execution is complete and exit the execution loop to determine whether there is a default exception handling function. If yes, it is called:

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 the User-Defined default Exception Handling Function
} Else {
Uncaptured exceptions
}
} Else {
No exception
}
Destroy_op_array (eg (active_op_array) tsrmls_cc );
Efree (eg (active_op_array ));


PHP exception Process
When PHP encounters a fatal error, zend_mongolout is directly used, and zend_mongolout causes the program process to directly skip the above Code segment. It can also be understood as directly exit (longjmp ), this leads to the failure of user_exception_handler.

I thinkArticleWhy? Is that clear?

Finally, you may have some questions about zend_handle_exception: If so, why does the zend_handle_exception exist at the end of every independently executed op array? In the simplest way, if a function does not throw, this opcode is obviously unnecessary? Hey, you are very smart. php 5.3 has already been adjusted according to your ideas. zend_handle_exception opline will be generated dynamically only at the throw moment.

PhP5 changelog:

Changed Exception Handling. Now each op_array doesn't contain zend_handle_exception opcode in the end. (Dmitry)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.