国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > PHP > 正文

深入解析PHP的引用計數機制

2020-03-22 20:25:33
字體:
來源:轉載
供稿:網友
PHP的變量聲明并賦值后,變量名存在符號表中,而值和類信息存在zval中,zval中包含四個變量,is_ref,refcount,html' target='_blank'>value,type,zval源碼如下
復制代碼 代碼如下:
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};

refcount表示value地址與其相同的zval共有多少個,refcount=0時,zval被銷毀
is_ref表示一個zval是否被引用,有“0”和“1”兩種狀態此處分析一下什么時候zval會被復制或者開辟新的內存空間呢
1.當is_ref=0,且refcount 1時,如果改變某個指向該zval的變量的值,會生成新zval,原zval的refcount--,例如:$a=1;$b=$a;$b=2;,zval將被復制,也就是說原先ab指向同一個zval,后來b會使用新開辟的zval

2.當is_ref=0,且refcount 1時,如果將zval賦值給某個引用變量,那么用來賦值和變量和被賦值的變量會使用同一個原zval,而其他指向原zval的變量將會指向一個新復制的zval,且refcount會被重新計算,例如:$a=1;$b=$a;$c=$a;$d= ,此時ad使用原zval,bc使用新復制出來的zval

3.當is_ref=1,且refcount 1時,如果將zval復制給某個非引用變量,該非引用變量會使用一個新復制的zval,元zval的refcount不變,例如:$a=1;$b= $c=$a,那么ab使用原zval,而c使用新復制的zval
type表示該zval的值類型,宏定義如下
復制代碼 代碼如下:
#define IS_NULL 0
#define IS_LONG 1
#define IS_DOUBLE 2
#define IS_BOOL 3
#define IS_ARRAY 4
#define IS_OBJECT 5
#define IS_STRING 6
#define IS_RESOURCE 7
#define IS_CONSTANT 8
#define IS_CONSTANT_ARRAY 9

value表示該zval的值,他也是個共同體,代碼如下
復制代碼 代碼如下:
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str;
HashTable *ht; /* hash table value */
zend_object_value obj;
} zvalue_value;

現在你知道php是如何類型變換的了,因為他的值存的其實是個可以代表任何類型的結構體,而具體的取值則根據type來決定是用共同體里的哪個變量來存值的

見下面的例子1
復制代碼 代碼如下:
.-----------
$a = 1;
$b = $a;
$c = $a;
.-----------
$d =
.-----------
$a = 2;
.-----------
$b = null;

查看refcount,is_ref,zval的變化
執行完第一部分后來看看輸出
1-----------------------------
a:(refcount=3, is_ref=0),int 1
b:(refcount=3, is_ref=0),int 1
c:(refcount=3, is_ref=0),int 1
可以看出來a,b,c使用同一個zval
再看執行完第二部分的
2----------------------------
a:(refcount=2, is_ref=1),int 1
b:(refcount=2, is_ref=0),int 1
c:(refcount=2, is_ref=0),int 1
d:(refcount=2, is_ref=1),int 1
注意此時a,d在一起了,他們使用同一個zval,而bc使用一個新生成的zval,同時重新計算兩個zval的refcount和is_ref
3----------------------------
a:(refcount=2, is_ref=1),int 2
b:(refcount=2, is_ref=0),int 1
c:(refcount=2, is_ref=0),int 1
d:(refcount=2, is_ref=1),int 2
可以知道ad這兩個is_ref=1的好基友的值是同時改變的
4----------------------------
a:(refcount=2, is_ref=1),int 2
b:(refcount=1, is_ref=0),null
c:(refcount=1, is_ref=0),int 1
d:(refcount=2, is_ref=1),int 2
bc由于他們的zval的is_ref=0,所以他們不是好基友,他們的值不會同時改變,于是bc的zval再次分裂,b = null c = 1
PHP教程

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 和政县| 凉城县| 图木舒克市| 保康县| 德钦县| 尖扎县| 福泉市| 富锦市| 孟州市| 潮安县| 江山市| 土默特左旗| 新沂市| 高尔夫| 石景山区| 莒南县| 和林格尔县| 兰西县| 诏安县| 綦江县| 武安市| 舒城县| 阜康市| 郁南县| 黄山市| 安宁市| 台山市| 柳江县| 个旧市| 瓦房店市| 集安市| 肇东市| 乌海市| 雅江县| 含山县| 奉化市| 台州市| 玉林市| 陈巴尔虎旗| 栖霞市| 灵宝市|