PHP 7.3.7 GNU gdb (GDB) 8.3
<?php $a = 'hello'; echo $a; $b = $a; echo $a; echo $b; $b = 'world'; echo $a; echo $b; /* result: root@MacBook-Pro-3:/home/code/php-demo# php73 string.php hellohellohellohelloworld */
該結果沒什麼異議,下面咱們來分三部分$a = 'hello';
$b = $a;
$b = 'world';
來看下底層變量的結構變化:php
$a = 'hello'; /* (gdb) p z $1 = (zval *) 0x102022080 (gdb) p *z $2 = {value = {lval = 4328543936, dval = 2.1385848552920513e-314, counted = 0x1020056c0, str = 0x1020056c0, arr = 0x1020056c0, obj = 0x1020056c0, res = 0x1020056c0, ref = 0x1020056c0, ast = 0x1020056c0, zv = 0x1020056c0, ptr = 0x1020056c0, ce = 0x1020056c0, func = 0x1020056c0, ww = { w1 = 33576640, w2 = 1}}, u1 = {v = {type = 6 '\006', type_flags = 0 '\000', u = {call_info = 0, extra = 0}}, type_info = 6}, u2 = {next = 0, cache_slot = 0, opline_num = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0, access_flags = 0, property_guard = 0, constant_flags = 0, extra = 0}} (gdb) p $2.value.str $3 = (zend_string *) 0x1020056c0 (gdb) p *$2.value.str $4 = {gc = {refcount = 1, u = {type_info = 70}}, h = 9223372247569412249, len = 5, val = "h"} (gdb) p *$2.value.str.val@5 $5 = "hello" */ echo $a;
變量a初始結構示意圖:shell
$b = $a; /* (gdb) p z $6 = (zval *) 0x102022080 (gdb) p *z $7 = {value = {lval = 4328543936, dval = 2.1385848552920513e-314, counted = 0x1020056c0, str = 0x1020056c0, arr = 0x1020056c0, obj = 0x1020056c0, res = 0x1020056c0, ref = 0x1020056c0, ast = 0x1020056c0, zv = 0x1020056c0, ptr = 0x1020056c0, ce = 0x1020056c0, func = 0x1020056c0, ww = { w1 = 33576640, w2 = 1}}, u1 = {v = {type = 6 '\006', type_flags = 0 '\000', u = {call_info = 0, extra = 0}}, type_info = 6}, u2 = {next = 0, cache_slot = 0, opline_num = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0, access_flags = 0, property_guard = 0, constant_flags = 0, extra = 0}} (gdb) p $7.value.str $8 = (zend_string *) 0x1020056c0 (gdb) p *$7.value.str $9 = {gc = {refcount = 1, u = {type_info = 70}}, h = 9223372247569412249, len = 5, val = "h"} (gdb) p *$7.value.str.val@5 $10 = "hello" */ echo $a; /* (gdb) p z $11 = (zval *) 0x102022090 (gdb) p *z $12 = {value = {lval = 4328543936, dval = 2.1385848552920513e-314, counted = 0x1020056c0, str = 0x1020056c0, arr = 0x1020056c0, obj = 0x1020056c0, res = 0x1020056c0, ref = 0x1020056c0, ast = 0x1020056c0, zv = 0x1020056c0, ptr = 0x1020056c0, ce = 0x1020056c0, func = 0x1020056c0, ww = { w1 = 33576640, w2 = 1}}, u1 = {v = {type = 6 '\006', type_flags = 0 '\000', u = {call_info = 0, extra = 0}}, type_info = 6}, u2 = {next = 0, cache_slot = 0, opline_num = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0, access_flags = 0, property_guard = 0, constant_flags = 0, extra = 0}} (gdb) p *$12.value.str $13 = {gc = {refcount = 1, u = {type_info = 70}}, h = 9223372247569412249, len = 5, val = "h"} (gdb) p *$12.value.str.val@5 $14 = "hello" */ echo $b;
變量a賦值給變量b時,二者共用一個_zend_string結構體,以下圖:php7
$b = 'world'; /* (gdb) p z $17 = (zval *) 0x102022080 (gdb) p *z $18 = {value = {lval = 4328543936, dval = 2.1385848552920513e-314, counted = 0x1020056c0, str = 0x1020056c0, arr = 0x1020056c0, obj = 0x1020056c0, res = 0x1020056c0, ref = 0x1020056c0, ast = 0x1020056c0, zv = 0x1020056c0, ptr = 0x1020056c0, ce = 0x1020056c0, func = 0x1020056c0, ww = { w1 = 33576640, w2 = 1}}, u1 = {v = {type = 6 '\006', type_flags = 0 '\000', u = {call_info = 0, extra = 0}}, type_info = 6}, u2 = {next = 0, cache_slot = 0, opline_num = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0, access_flags = 0, property_guard = 0, constant_flags = 0, extra = 0}} (gdb) p $18.value.str $19 = (zend_string *) 0x1020056c0 (gdb) p *$18.value.str $20 = {gc = {refcount = 1, u = {type_info = 70}}, h = 9223372247569412249, len = 5, val = "h"} (gdb) p *$18.value.str.val@5 $21 = "hello" */ echo $a; /* (gdb) p z $22 = (zval *) 0x102022090 (gdb) p *z $23 = {value = {lval = 4328544000, dval = 2.1385848869122527e-314, counted = 0x102005700, str = 0x102005700, arr = 0x102005700, obj = 0x102005700, res = 0x102005700, ref = 0x102005700, ast = 0x102005700, zv = 0x102005700, ptr = 0x102005700, ce = 0x102005700, func = 0x102005700, ww = { w1 = 33576704, w2 = 1}}, u1 = {v = {type = 6 '\006', type_flags = 0 '\000', u = {call_info = 0, extra = 0}}, type_info = 6}, u2 = {next = 0, cache_slot = 0, opline_num = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0, access_flags = 0, property_guard = 0, constant_flags = 0, extra = 0}} (gdb) p $23.value.str $24 = (zend_string *) 0x102005700 (gdb) p *$23.value.str $25 = {gc = {refcount = 1, u = {type_info = 70}}, h = 9223372247587566957, len = 5, val = "w"} (gdb) p *$23.value.str.val@5 $26 = "world" */ echo $b;
當變量b從新賦值時,會啓用一個新的_zend_string結構體,以下圖:網站
更多內容見我的網站spa