weakreference 由php的call_user_func傳reference引發的思考

來源:互聯網
上載者:User
問題的提出
網友bercmisir在院內留言,針對php手冊中的call_user_func函數的文檔一事,大致如下:
http://php.net/manual/en/function.call-user-func.php
其中parameter下有這樣一句話:
Note: Note that the parameters for call_user_func() are not passed by reference.
簡單地翻譯一下,是說這個函數的參數是不能依靠引用來傳遞的。
還有一個例子:

複製代碼 代碼如下:


error_reporting(E_ALL);
function increment(&$var)
{
$var++;
}
$a = 0;
call_user_func('increment', $a);
echo $a."\n";
call_user_func_array('increment', array(&$a)); // You can use this instead before PHP 5.3
echo $a."\n";
?>


輸出是:
0
1
而網友bercmisir的問題在於:
call_user_func('increment', $a);輸出是0,而call_user_func('increment', &$a);卻輸出是1,明明說不能依靠引用來傳遞。
尋根溯源
然後再進一步尋根溯源,這個Note的資訊其實是http://bugs.php.net/bug.php?id=24931這個bug中最後處理的結果。
並且在call_user_func('increment', &$a);雖然輸出了1的結果,但一般情況下,會有一個警告資訊:Deprecated: Call-time pass-by-reference has been deprecated。
這是什麼原因呢?
先看一個例子:

複製代碼 代碼如下:


error_reporting(E_ALL);
function increment(&$var)
{
$var++;
}
$x = 1;
increment($x);
echo $x;
?>


結果為2,並且沒有類似expected to be a reference, value given的警告資訊,相反地,如果將第8行代碼修改為&$x,將得到一個廢除警告。從而得以驗證,其實PHP在傳遞過程中,變數會根據形參需要的到底是引用還是值來自行決定傳輸的是引用還是值,並不需要顯式地傳遞(相反顯式傳遞是即將被廢除的)。
繼續深入
http://www.php.net/manual/en/language.references.pass.php
在php手冊中,介紹引用的傳遞一節,在中間位置有一個Note說到:在函數調用時是不需要傳引用的(也就是上節所說的顯式調用),在5.3中如果顯式調用會出來一個廢除警告。
分析源碼
有人說:在php中寫入,everything is a reference。
查閱php源碼,在./Zend/zend_compile.c的1579行有函數定義zend_do_pass_param。(php5.2.13)
其中有這樣一句判斷:
if (original_op == ZEND_SEND_REF && !CG(allow_call_time_pass_reference)) {列印廢除警告。}
大概意思就是說,在傳遞的是引用,並且php.ini的allow_call_time_pass_reference為否的話,列印警告。
再看zend_do_pass_param使用的地方,可以發現是在parser階段時,根據參數ZVAL結構體中元素的定義,來傳遞到底是var還是value還是reference。(php5.2.13 ./Zend/zend_language_parser.y/c 451/3593)
結論
引用其實類似linux裡的檔案永久連結一樣,但和C語言中的指標是不相同的,在parser階段php會根據上下文環境自行判斷是傳引用還是值。而本文所提到的call_user_function並不會自行判斷傳的是引用還是值。所以前面的例子call_user_function在傳值的時候不管用,而在傳引用的時候得出了正確結果(但其實還有一個廢除警告)。

以上就介紹了weakreference 由php的call_user_func傳reference引發的思考,包括了weakreference方面的內容,希望對PHP教程有興趣的朋友有所協助。

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    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.