日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

php sslbug,PHP错误抑制符(@)导致引用传参失败Bug的分析

發布時間:2023/12/10 php 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php sslbug,PHP错误抑制符(@)导致引用传参失败Bug的分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

看下面的例子:

$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 sslbug,PHP错误抑制符(@)导致引用传参失败Bug的分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。