源码网,源码论坛,源码之家,商业源码,游戏源码下载,discuz插件,棋牌源码下载,精品源码论坛

 找回密码
 立即注册
楼主: ttx9n

[PHP编程] PHP错误抑制符(@)导致引用传参失败Bug的分析

[复制链接]

7万

主题

861

回帖

32万

积分

论坛元老

Rank: 8Rank: 8

积分
329525
发表于 2011-5-2 14:08:56 | 显示全部楼层 |阅读模式
今天cici网友发来一个问题, 说是在函数调用参数前面使用错误抑制符号(@)的时候, 貌似引用传参就失效了. 他想让我帮他解答为什么. 看下面的例子:
复制代码 代码如下:
<?php
$array = array(1,2,3);
function add (&$arr) {
$arr[] = 4;
}
add(@$array);
print_r($array);
/**
此时, $array没有改变, 输出:
Array
(
[0] => 1
[1] => 2
[2] => 3
)
*/
add($array);
print_r($array);
/**
不使用错误抑制的情况下, 输出正常:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
*/
?>

这个问题, 我之前没有遇到过, 所以首先去找找相关资料, 看看有没有现成的答案, Goolge了一番, 发现虽然有人已经向PHP报了类似的Bug:http://bugs.php.net/bug.php?id=47623, 但PHP官方还没有解决, 也没有给出答复.

没办法, 只能自己分析了, 之前我曾经在文章中介绍过错误抑制符的原理( 深入理解PHP原理之错误抑制与内嵌HTML), 从原理上来说, 错误抑制只是修改了error_reporting的level, 按理来说不会影响到上下文之间的函数调用的机制. 只能通过实地试验了.

经过gdb跟踪, 发现在使用了错误移植符以后, 函数调用前的传参opcode不同:
复制代码 代码如下:
//没有使用错误抑制符的时候
OPCODE = SEND_REF
//使用了错误抑制符号以后
OPCODE = SEND_VAR_NO_RE

问题初步定位了, 但是造成这种差异的原因又是什么呢?

既然OPCODE不同, 那么肯定是在语法分析的阶段, 走了不同的分支了, 想到这一层, 问题也就好定位了,

原来, PHP语法分析阶段, 把形如 “@”+expr的条目, 规约成了expr_without_variable, 而这种节点的意义就是没有变量的值, 也就是字面值, 我们都知道字面值是不能传递引用的(因为它不是变量), 所以, 就会导致这种差异.

具体过程如下:
1. 语法分析阶段:
复制代码 代码如下:
expr_without_variable:
//...有省略
| '@' { zend_do_begin_silence(&$1 TSRMLS_CC); }
expr { zend_do_end_silence(&$1 TSRMLS_CC); $$ = $3; }
//此处走了ZEND_SEND_VAL分支
non_empty_function_call_parameter_list:
expr_without_variable { ....} //错误的走了这个分支
| variable {..... } //正常情况

所以导致在编译期间, 生成了不同的OPCODE, 也导致了问题的表象.
最后, 我已经把原因在PHP的这个bug页做了说明, 有兴趣的可以去看看我的烂英语水平. 最后谢谢cici网友提供的这个有趣的问题.

回复

使用道具 举报

0

主题

2万

回帖

0

积分

中级会员

Rank: 3Rank: 3

积分
0
发表于 2022-9-21 15:20:34 | 显示全部楼层
的vgdsvsdvdsvdsvds
回复 支持 反对

使用道具 举报

1

主题

2万

回帖

93

积分

注册会员

Rank: 2

积分
93
发表于 2022-12-17 13:59:49 | 显示全部楼层
非常vbcbvcvbvcb
回复 支持 反对

使用道具 举报

1

主题

2万

回帖

182

积分

注册会员

Rank: 2

积分
182
发表于 2022-12-29 05:10:34 | 显示全部楼层
2222222222222222
回复 支持 反对

使用道具 举报

0

主题

2万

回帖

87

积分

注册会员

Rank: 2

积分
87
发表于 2023-6-24 18:11:43 | 显示全部楼层
你们谁看了弄洒了可能
回复 支持 反对

使用道具 举报

5

主题

2万

回帖

69

积分

注册会员

Rank: 2

积分
69
发表于 2023-9-1 21:59:43 | 显示全部楼层
管灌灌灌灌灌灌灌灌灌灌
回复 支持 反对

使用道具 举报

8

主题

2万

回帖

52

积分

注册会员

Rank: 2

积分
52
发表于 2023-9-14 13:36:47 | 显示全部楼层
你们谁看了弄洒了可能
回复 支持 反对

使用道具 举报

3

主题

2万

回帖

301

积分

中级会员

Rank: 3Rank: 3

积分
301
发表于 2023-10-22 15:47:20 | 显示全部楼层
这个源码不错啊
回复 支持 反对

使用道具 举报

6

主题

2万

回帖

247

积分

中级会员

Rank: 3Rank: 3

积分
247
发表于 2024-3-9 22:36:39 | 显示全部楼层
怕怕怕怕怕怕怕怕怕怕怕怕怕怕
回复 支持 反对

使用道具 举报

0

主题

2万

回帖

0

积分

中级会员

Rank: 3Rank: 3

积分
0
发表于 2024-4-13 16:23:04 | 显示全部楼层
啊啊啊啊啊啊啊啊啊啊啊啊啊啊
回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

手机版|小黑屋|网站地图|源码论坛 ( 海外版 )

GMT+8, 2025-2-6 04:45 , Processed in 0.066907 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表