PHP error blocker (@): analysis of the Bug that fails to reference parameter passing _ php skills

Source: Internet
Author: User
Tags php error
Today, when the cici user sent a question saying that the error suppression symbol (@) was used before the function call parameter, it seems that the parameter passing through the reference will become invalid. he wanted me to answer why. see the following example:

The code is as follows:


$ Array = array (1, 2, 3 );
Function add (& $ arr ){
$ Arr [] = 4;
}
Add (@ $ array );
Print_r ($ array );
/**
At this time, $ array does not change and the output is:
Array
(
[0] => 1
[1] => 2
[2] => 3
)
*/
Add ($ array );
Print_r ($ array );
/**
If error suppression is not used, the output is normal:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
*/
?>


This problem, I have not met before, so first go to the relevant information to see if there is a ready-made answer, Goolge a bit, found that although someone has reported a similar Bug to PHP: http://bugs.php.net/bug.php? Id = 47623, but PHP has not been resolved yet and no response is provided.

No way, I can only analyze it by myself. I have previously introduced the principle of the error blocker in my article (a deep understanding of PHP principles, error blocker and embedded HTML). in principle, error suppression only modifies the level of error_reporting, which does not affect the function calling mechanism between contexts. it can only be tested in the field.

After gdb tracking, it is found that the parameter passing opcode before the function call is different after the error port is used:

The code is as follows:


// When the error blocker is not used
OPCODE = SEND_REF
// After the error suppression symbol is used
OPCODE = SEND_VAR_NO_RE


The problem was initially located, but why is the difference?

Since OPCODE is different, it must have taken different branches in the syntax analysis phase. when we think of this layer, the problem will be well located,

Originally, in the PHP syntax analysis phase, the entry in the form of "@" + expr is reduced to expr_without_variable, and the meaning of this node is that there is no variable value, that is, the literal value, we all know that the literal value cannot be referenced (because it is not a variable), so this difference will occur.

The specific process is as follows:
1. syntax analysis stage:

The code is as follows:


Expr_without_variable:
//... Omitted
| '@' {Zend_do_begin_silence (& $1 TSRMLS_CC );}
Expr {zend_do_end_silence (& $1 TSRMLS_CC); $ = $3 ;}
// The ZEND_SEND_VAL branch is used here.
Non_empty_function_call_parameter_list:
Expr_without_variable {...} // The branch is incorrect.
| Variable {...} // normal situation


Therefore, different opcodes are generated during compilation, which also leads to the appearance of problems.
Finally, I have explained the cause on the PHP bug page. if you are interested, you can check out my poor English skills. finally, thank you for providing this interesting question.

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.