摘要:學習需要知其然而知其所以然,PHP底層相關就是這類知識,從上文中知道聲明一個變量,將會產生一個結構體,那么在傳值賦值和引用賦值時, 結構體是如何變化的呢?
從上文(http://www.cwfssh.com/html/php/173.html) 中知道聲明一個變量,將會產生一個結構體,那么在傳值賦值和引用賦值時, 結構體是如何變化的呢?
一、變量的傳值賦值:
以: $a = 3 ; $b = $a為例,此時并沒有再次產生結構體,而是2個變量共用1個結構體,refcount__gc 值為2。
$a = 3
此時的結構體:
{ value:3 type:IS_LONG refcount__gc:1 is_ref__gc:0 }
$b = $a;
此時$a和$b共用一個結構體:
{ value:3 type:IS_LONG refcount__gc:2 is_ref__gc:0 }
思考: a, b指向同一個結構體, 那么,修改a,或b ,對方會不會受干擾?
答: 不會,
因為兩者,有一方修改時,將會造成結構體的分裂。
$b = 5; //此時修改變量的值
結構體如下:
$a的結構體是:
{ value:3 type:IS_LONG refcount__gc:1 is_ref__gc:0 }
$b的結構體是:
{ value:5 type:IS_LONG refcount__gc:1 is_ref__gc:0 }
結構體一開始共用,到某一方要修改值時,才分裂。這種特點稱為Copy-on-Write,也就是寫時復制。
二、變量的引用賦值:
當引用賦值時, 雙方共用一個結構體(is_ref__gc=1)
$a = 1;
此時的結構體:
{ value:1 type:IS_LONG refcount__gc:1 is_ref__gc:0 }
$b = &$a;
此時$a和$b共用一個結構體:
{ value:1 type:IS_LONG refcount__gc:2 is_ref__gc:1 }
is_ref__gc:1表示引用賦值,此時,如果修改$a和$b任意一個值,結構體不會分裂,$a和$b兩個值也將都會修改;
三、強制分裂:
那么現在有這樣一個代碼:
$a = 3; $b = $a; $c = &$a; $c = 5; echo $a.$b.$c; //535
為什么會是這樣的結果呢,這跟上面我們講的結構體不一樣呢?
原因就是此時發生了強制分裂!
當is_ref__gc[引用屬性]從0->1,如果refcount__gc>1,那么就會發生強制分裂。
這個就是強制分裂。原本已經經過傳值賦值的變量,再次引用賦值出去。被傳值賦值的變量就會被分裂出一個結構體,簡單可以理解為:在引用變量主動賦值前,該變量傳值賦值過,就會發生強制分裂。
上述代碼中:
$b強制分裂出一個結構體:
{ value:3 type:IS_LONG refcount__gc:1 is_ref__gc:0 }
$a個$c共用一個結構體:
{ value:5 type:IS_LONG refcount__gc:2 is_ref__gc:1 }
注意:在數組中慎用引用賦值,例如:
$arr = array(0,1,2,3); $x = &$arr[1]; $tem = $arr; $arr[1] = 999; echo $tem[1]; //結果為 999
網友評論:
還不錯啊
2018-11-01 09:43:14 回復
網友評論:
管理員 回復 YzmCMS博客網友 :由于個人時間有限,所以會抽時間不定期的更新文章。
2018-10-29 09:54:19 回復
網友評論:
最近的更新頻率可以
2018-10-29 02:45:54 回復