完全理解PHP中的變量引用
阿新 • • 發佈:2018-06-28
當我 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中的變量引用