宝哥软件园

PHP7内核详细参考说明

编辑:宝哥软件园 来源:互联网 时间:2021-08-27

问题

上一章说REFERENCE是PHP5中的一个标志位,但是PHP7之后,我们把它改成了一个新的类型: is _ reference。但是引用是一个非常常见的应用,所以这个变化带来了很多变化,也给我们开发PHP7的时候带来了很多bug,因为我们有时候会忽略处理这个类型。

最简单的情况,在处理各种类型的时候,我们应该从现在开始多考虑这种新类型。例如,在PHP7中,这种代码形式变得非常常见。

try _ again : swtich(Z _ TYPE _ P(zv)){ case IS _ string : break;案例IS_ARRAY:中断;case IS _ reference : zv=Z _ REFVAL _ P(zv);//取消引用goto重试;打破;}如果自己写扩展,忘记考虑这个新类型,会导致问题。

为什么呢?那么,既然这个新类型会带来这么多问题,为什么要用它把引用变成类型呢?为什么不用标志位呢?

总之,我们必须这样做。-_ #

如前所述,Hashtable直接存储zval,那么两个zval如何在符号表中共享一个数值呢?对于字符串这样的复杂类型来说没问题。似乎我们可以在zend_refcounted结构中添加一个标志位来表示它是一个引用。但是,这一个也会遇到写时更改带来的复制。但是我们知道,在PHP7中,有些类型是直接存储在zval中的,比如IS_LONG,但是引用类型需要引用计数。那么如何表示一个IS_LONG和IS _ REFERNCE的zval呢?

为此,我们创造了这种新型:

如图所示,reference是一个新类型:zend_reference。对于IS _ REFERNCE类型的zval,则为zval。价值。Ref是指向zend_reference的指针,其中包含引用计数和一个ZVal。ZVal的特定值存在于zval.value.ref-val中。

因此,对于IS_LONG的引用,使用IS _ REFERNCE类型的zval,它指向zend_reference,并且这个zend_reference-val是IS_LONG类型的zval。

考虑到下面的代码:WritePHP使用引用计数来进行简单的垃圾收集

?php1。$ val=影响力';2.$ ref=$ val3.$ copy=$ val?$ref和$val指的是同一个zval。在PHP5中,我们通过计数为2且引用标志为1的引用来指示这种情况。当将$val复制到$copy时(第3行),我们发现$val是一个计数大于1的引用,因此我们需要复制这个zval。

在PHP7中,情况变得简单多了。首先,当引用被分配给$ref(第2行)时,会生成一个IS _ REFERNCE类型。然后,因为此时有两个变量引用它,zend_reference结构的引用计数zval.value.ref-gc.refcount为2。

当分配给$copy(第3行)时,发现$val是引用,所以让$copy指向zval.value.ref-val,即字符串值为laruence的zval,然后对zval的引用计数1,即z val . value . ref-val . value . str . GC . ref count为2。和

因此,这很好地解决了上一章提到的PHP5的经典问题。例如,当我们在PHP7下运行上一章的问题时,我们得到的结果是:

$ PHP-7.0/SAPI/CLI/PHP/tmp/1 . phpussed 0.00021380008539 used 0.000001 . 000001 . 000001 . 000001 . 00001 . 000001 . 000001

可以看出没有复制,不会造成任何性能问题。

以上就是边肖介绍的PHP7内核的Reference的详细讲解和集成,希望对大家有所帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!

更多资讯
游戏推荐
更多+