The abnormal mechanism of PHP principle in depth analysis _php skill

Source: Internet
Author: User
Tags exception handling try catch
What is the principle of the exception mechanism of PHP?

What is the final zend_handle_exception of each OP array that can be executed independently in PHP?

Let's start with a question, last week, Blue5tar asked a question: "For the following code, OnError clearly executed, but Onexception did not execute, why?"

Copy Code code 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 never name a file by my name, so this file does not exist.
Require ("laruence.php");

Run Result:
Copy Code code as follows:

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

First, we need to know that require throws two errors before and after it contains a problem that cannot be found.
Copy Code code as follows:

1. WARNING: When PHP tries to open this file, it throws.
2. E_compile_error: The function that opens a file from PHP returns a failure to throw after

And we know that Set_error_handler cannot catch E_compile_error errors:

The following error types cannot is 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 the exception thrown in OnError is not captured by the default Exception_handler?

This is going to talk about the exception mechanism of PHP.

Learn about opcode (the opcodes of PHP's theory) knows that before PHP5.3, each of the last opcode of op array (file, function, method) that can run independently is zend_handle_exception, And what is this opcode for?

Originally in PHP, when there is an exception is throw, will jump to the last line of each OP array, to execute this zend_handle_exception, the pseudo code is as follows:
Copy Code code as follows:

void On_throw_exception (Zval *exception tsrmls_dc) {
1. To determine whether there have been exceptions thrown
2. Record exception
3. Record the serial number of the OP line to be executed
4. The next OP line ordinal to be executed = The last of the current OP array
}

Well, as with rewriting IP registers, rewrite the sequence of op line to be executed, changing the flow of the program, so that it will enter into the zend_handle_exception processing logic.

In Zend_handle_exception, the exception is judged to be in a try catch.

Copy Code code as follows:

If so, place the next op line to be executed as the first catch and continue execution.
If not, destroy some unwanted variables, and opline, and then end the execution directly

Some students have to ask: "That Set_exception_handler set the exception of the default processing function (User_exception_handler) when does it work?"

Well, it's not until after the execution has finished exiting the loop that there is a default exception handler, if it is called:

Copy Code code as follows:

Perform
Zend_execute (EG (Active_op_array) tsrmls_cc);
if (EG (exception)) {
if (EG (User_exception_handler)) {
Calling the user-defined default exception handling function
} else {
An exception that was not caught
}
} else {
No exceptions.
}
Destroy_op_array (EG (Active_op_array) tsrmls_cc);
Efree (EG (Active_op_array));


PHP Exception Flow
and PHP encountered fatal error, will be directly zend_bailout, and Zend_bailout will cause the program flow directly skip the above code section, can also be understood as direct exit (LONGJMP), which led to the User_exception_ Handler has no chance of action.

To understand these, I want to start the article on the question why? It's clear, isn't it?

Finally, with regard to zend_handle_exception, perhaps some students will have the question: if so, then why each can be executed independently of the OP array finally have this zend_handle_exception? The simplest, if a function does not throw, then this opcode is obviously not needed ah? Hey, you're smart, PHP 5.3 starts, has been adjusted according to your ideas. Only in the throw moment, will the dynamic generation of zend_handle_exception opline.

PHP5 Changelog:

Changed exception handling. Now all 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.