php - @amazeUI - 2017-02-05 08:41:26
php数组在zval中的联合体中是一个指针,这个指针指向的是一张哈希表,这个哈希表对应一个或多个zval结构体。比如$a = array('a','b','c');会产生一个结构体,这个结构体的联合体会有一个指针,指向一张哈希表,这张哈希表存着三条记录,可以简单的将哈希表理解为一个关联数组,一共有三个键值对,0对应着一个zval结构体的内存地址,这个zval的联合体内的值为a。
$a = array('a','b','c');
$b = $a;
以上为传值赋值,会产生几个结构体呢,应该是四个结构体,全局的符号表中会有两条记录。如果在这两句后面加上$a[0]=1;内存中的这两个变量会如何变化呢,这点与普通类型的变量不同。当传值赋值时,有行为会改变结构体的话会分裂,在数组这里,分裂的仅仅是一张哈希表,也就是说上面三句代码执行,将会多出一张哈希表,这张哈希表是$b的,这个$b的哈希表中的键1和键2其实还是指向的$a的键1和键2指向的zval的地址,键0将重新指向一个新产生的值为1的zval中。
数组键的引用赋值引发的一个现象
$a = array(1,2,3);
$b = &$a[1];
$c = $a;
$a[1] = 5;
echo $c[1];
此时实际上输出的就是5了,因为$b的引用赋值已经将基础单元值为2的zval结构体的类型改为了引用类型,而php只会去判断第一层的zval类型,所以导致$a和$c指向的还是同一张符号表。
以上说的符号表是全局符号表,有全局就肯定也有局部,局部符号表指的是程序进行过程中遇到的自定义函数里的变量存放的地方。函数里的局部符号表就存在函数的结构体里,函数中的静态变量存放在op_array里,也是一个指针指向一张符号表。而常量单独在整个内存中占用一张符号表。