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
里,也是一个指针指向一张符号表。
而常量单独在整个内存中占用一张符号表。
原文链接:php的数组-PHP
网友评论