1. 程式人生 > >完全理解PHP中的變量引用

完全理解PHP中的變量引用

當我 int 查看 原則 struct hello 繼續 常用 引用傳遞

在PHP面試中,經常會遇到這樣一道問題:
什麽是變量引用,用什麽符號表示?

這個其實很簡單,變量引用簡單來說就是不同的變量名稱指向同一個值。用&符號表示。

初學PHP,都知道變量的聲明與賦值為:

$a = str_replace("hello world",40);

我們可以將值再賦給$b

$b = $a;

這樣$a,$b都等於hello world,那在內存中是不是開辟了2個空間來存儲呢?我們可以使用memory_get_usage()來查看:

$a =str_replace( ‘hello world‘,40);
var_dump(memory_get_usage());
$b = $a;
var_dump(memory_get_usage());

你會發現內存的值沒有變化。也就是說變量a和b都指向了同一個內存地址。

這裏設計PHP的一個重要原則,是COW,即copy on write,意思就是說只有在真的寫入的時候,才會復制出一塊內存地址。

那我們繼續看:

var_dump(memory_get_usage());
$a = str_repeat(‘hello world‘,40);
var_dump(memory_get_usage());
$b = $a;
var_dump(memory_get_usage());
$a = str_repeat(‘hello teacher‘,40);
var_dump(memory_get_usage());

以上的代碼,就會發現當$a重新賦值時,內存占用發生了變化 。

那再來看變量引用

var_dump(memory_get_usage());
$a = str_repeat(‘hello world‘,1);
var_dump(memory_get_usage());
$b = &$a;
var_dump(memory_get_usage());
$a = str_repeat(‘hello teacher‘,1);
var_dump(memory_get_usage());

echo $a;
echo ‘----------‘;
echo $b;

使用&符號以後,變量a和b使用一塊內存地址,a發生變化後,b也隨著變化.


往底層來考慮

zval是php中最重要的數據結構之一。

struct _zval_struct {
    zvalue_value value;     /* value */
    zend_uint refcount__gc;  /* variable ref count */
    zend_uchar type;          /* active type */
    zend_uchar is_ref__gc;    /* if it is a ref variable */
};
typedef struct _zval_struct zval;

以上是一段C語言代碼,這是zval的定義,一共有四個值,
zvalue是變量的實際值
uchar 是變量的的類型,比如PHP中的常用變量:bool、int、float、array、string、object、NULL等
refcount_gc:是一個計數器,當我們把變量覆值給另一個變量時,計數器加1,unset計數器減1,簡單來說就是有多少個變量指向它。
is_ref__gc:這個值分為0和1,代表是否為引用變量

結論就是PHP底層的數據結構設計 決定了引用變量和變量賦值的原理。

註:對象類型本身就是引用傳遞。

完全理解PHP中的變量引用