程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> php引用計數與變量引用

php引用計數與變量引用

編輯:關於PHP編程

php引用計數與變量引用


 每個php5.5變量都存儲在一個叫做zval的變量容器中。     一個zval變量容器,除了包含變量的類型與值外,還包含兩個字節的額外信息:       1、第一個是“is_ref”,是個bool型,用來標識這個變量是否屬於引用集合(reference set),若屬於則其值為1,否則為0。         有個這個變量php引擎就能夠將普通變量與引用變量區分開來。       2、第二個是“refcount”,用來表示指向這個zval變量(符號)的個數。每個符號都有作用域(scope),那些主腳本和函數或者方法也都有作用域。         所有的符號都存在一個符號表中。     當一個變量被賦值一個常量值時,就會生成一個zval變量容器,如下例:   <?php     $a = "Hello world"; ?>   這個時候執行以下程序得到$a變量指向zval容器中的is_ref與refcount值   <?php     $a = "Hello world";     print_r(xdebug_debug_zval('a')); ?> a: (refcount=1, is_ref=0)='Hello world'   下面,我們進行如下實驗,來探討引用賦值與普通賦值。     首先,使$b指向$a,查看is_ref、 refcount,如下:   <?php     $a = "Hello world";       $b = $a;     print_r(xdebug_debug_zval('a'));     print_r(xdebug_debug_zval('b')); ?> a: (refcount=2, is_ref=0)='Hello world' b: (refcount=2, is_ref=0)='Hello world'   讓$b引用$a,查看is_ref    refcount,如下   <?php     $a = "Hello world";       $b = &$a;     print_r(xdebug_debug_zval('a'));     print_r(xdebug_debug_zval('b')); ?> a: (refcount=2, is_ref=1)='Hello world' b: (refcount=2, is_ref=1)='Hello world'   從上我們可以分析出,當有變量引用相應zval容器時,is_ref為1。     我們進一步分析,我們把$b 引用$a,$c指向$a,如下    
<?php
    $a = "Hello world";  
    $b = &$a;
    $c = $a;

    print_r(xdebug_debug_zval('a'));
    print_r(xdebug_debug_zval('b'));
    print_r(xdebug_debug_zval('c'));
?>

 

    打印結果如下   a: (refcount=2, is_ref=1)='Hello world' b: (refcount=2, is_ref=1)='Hello world' c: (refcount=1, is_ref=0)='Hello world'   可見,這個時候php5.5引擎為$c重新建立了一個zval容器,容器中的數據類型、值與$a指向的容器中的完全相同,不同的是其refcount與is_ref的值。        因此,我們可以看出,php5.5的zval容器中的is_ref變量要麼標識引用集合,要麼標識普通集合,當兩者都有時,他將克隆zval容器,來解決沖突問題。          總結:     1、在php5.5以後,“變量賦值”都是指向賦值,即將某個變量指向特定的zval容器。     2、“變量引用”則是將變量與變量進行綁定,若綁定的變量中有一個變量改變了指向,則相互綁定的其他變量的指向也隨著改變。       若變量重新引用變量,則其原來的變量綁定解除,轉而綁定新的變量。如下代碼:     
<?php
function foo(&$var)
{
    $var =& $GLOBALS["baz"];
}
foo($bar);
?>

 

    這將使 foo 函數中的 $var 變量在函數調用時和 $bar 綁定在一起,但接著又被重新綁定到了 $GLOBALS["baz"] 上面。不可能通過引用機制將 $bar 在函數調用范圍內綁定到別的變量上面,因為在函數 foo 中並沒有變量$bar(它被表示為 $var,但是 $var 只有變量內容而沒有調用符號表中的名字到值的綁定)。可以使用引用返回來引用被函數選擇的變量。    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved