四虎精品视频-四虎精品成人免费网站-四虎黄色网-四虎国产视频-国产免费91-国产蜜臀97一区二区三区

PHP錯誤抑制符(@)導致引用傳參失敗Bug的分析

看下面的例子:
復制代碼 代碼如下:
<?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網友提供的這個有趣的問題.

php技術PHP錯誤抑制符(@)導致引用傳參失敗Bug的分析,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 张鸿昌| 又造句二年级上册| 三人越谷文言文翻译| 2024年6月思想汇报| 纵横四海 电影| 韩国三级播放| 卫途轮胎| 恋爱中的城市 电影| 国家地理频道| 工会会员登记表个人简历填写| 活动评价| 男同视频在线| 初恋50次 电影| 黄真伊| 一路向北 免费观看 电影在线观看| 二年级100个数学应用题| 吻戏韩国| 朱砂手串的功效与作用佩戴禁忌| 福禄寿| 荒岛大逃亡电影在线观看| 极地重生 电影| 原来琪琪电影| 日韩女同性恋| 武林外史电视剧免费观看| 杰西卡·布朗·芬德利| 小数除法竖式50道带答案| 《我的美女老板》电视剧| 郭明翔| 视频爱爱| 艳妇乳肉豪妇荡乳ⅹxxo电影| 深流 电视剧| 电影《uhaw》免费观看| 洛嘉| 二年级合并综合算式题| 艳女十八式无删除版| 婷婷sese| 黄姓的研究报告| 王李丹妮全部三级| 赫伯曼电影免费观看| 新女婿时代电视剧免费观看| 麻豆视频网站|