PHP5 zval容器与PHP7 zval容器。参考资料及;变量现在存储了吗?
我遵循一个教程&阅读一些关于如何使用zval(zend-value)容器在PHP中存储变量的文章。这些文章中的大多数似乎都在跟踪&从有关的文档中获取信息。我对PHP的核心是如何实现PHP5 zval容器与PHP7 zval容器。参考资料及;变量现在存储了吗?,php,php-internals,Php,Php Internals,我遵循一个教程&阅读一些关于如何使用zval(zend-value)容器在PHP中存储变量的文章。这些文章中的大多数似乎都在跟踪&从有关的文档中获取信息。我对PHP的核心是如何实现zvalstruct感到好奇,因此我打开了PHP8的源代码&它看起来与那些文章或PHP.net所描述的不同。例如,在php.net中,它声明zval容器包含refcount和is_ref,但当我在PHP8中查看时,这两个都不是源代码的一部分。因此,经过一些挖掘,我发现refcount&is_ref是PHP5中zval结
zval
struct感到好奇,因此我打开了PHP8的源代码&它看起来与那些文章或PHP.net所描述的不同。例如,在php.net中,它声明zval
容器包含refcount
和is_ref
,但当我在PHP8中查看时,这两个都不是源代码的一部分。因此,经过一些挖掘,我发现refcount
&is_ref
是PHP5中zval
结构的一部分,但后来在PHP7中发生了变化,引入了性能优化,包括更好的内存管理
这是PHP5中zval的结构代码:
struct _zval_struct {
zvalue_value value;
zend_uint refcount__gc;
zend_uchar type;
zend_uchar is_ref__gc;
};
这是从PHP8中的PHP7开始的样子:
struct _zval_struct {
zend_value value; /* value */
union {
uint32_t type_info;
struct {
ZEND_ENDIAN_LOHI_3(
zend_uchar type, /* active type */
zend_uchar type_flags,
union {
uint16_t extra; /* not further specified */
} u)
} v;
} u1;
union {
uint32_t next; /* hash collision chain */
uint32_t cache_slot; /* cache slot (for RECV_INIT) */
uint32_t opline_num; /* opline number (for FAST_CALL) */
uint32_t lineno; /* line number (for ast nodes) */
uint32_t num_args; /* arguments number for EX(This) */
uint32_t fe_pos; /* foreach position */
uint32_t fe_iter_idx; /* foreach iterator index */
uint32_t property_guard; /* single property guard */
uint32_t constant_flags; /* constant flags */
uint32_t extra; /* not further specified */
} u2;
};
因此,我试图找到一些关于这方面的更新/相关信息,但似乎找不到一个好的解释,其中包括一些与PHP5相比的说明,或者php.net上的文档是否仍然相关?从PHP7开始,ref计数是否不再重要,或者它现在如何处理引用。在它依赖is_ref
来确定是应该在写入时复制,还是仅仅指向相同的zval
容器之前。写上拷贝机制现在是如何工作的
例如:
$a = 1;
$b = $a;
这将在PHP5中有一个zval
容器,其中$x
和$y
符号都指向该容器,如果$a
或$b
更改了值,它只会创建容器的副本,但根据我的理解,由于PHP7,它从一开始就有两个zval
容器,因为该值是一个简单的标量类型int
。它什么时候进行写时拷贝
我不懂C语言,这就是为什么我很难通过查看源代码来理解发生了什么,而我在网上找到的信息与PHP的当前状态不符。@prieber,因为它与源代码不符。我懂一点C语言,但还不到能读懂所有东西的程度。但我知道的足够多,可以告诉你,文档所陈述的内容与代码中的内容是不同的。正如我在上面展示的代码,PHP中的当前代码没有refcount&is\u ref字段,所以我不确定它是如何进行ref计数的&现在引用是如何工作的如果你认为这是错误的,告诉他们-。(和下一页)可能有用。refcounting的核心思想保持不变,但是从zval转移到hold结构。是的,没错。每个变量都有一个单独的zval,与类型无关。在本例中,$a和$b都是指向同一对象的单独ZVAL。