Heim  >  Artikel  >  Backend-Entwicklung  >  《PHP核心技术与实践》PHP内核中的变量

《PHP核心技术与实践》PHP内核中的变量

WBOY
WBOYOriginal
2016-06-20 12:35:591038Durchsuche

要编写PHP扩展就不可避免要接触PHP内核中变量的表示方式,所以必须了解PHP变量在内核中的存储方式和使用方法。

  1. PHP变量在内核中的存储方式

    PHP是弱类型的语言,也就是说一个PHP变量可保存任何的数据类型,但PHP是由强类型的C语言来编写的,为此在Zend引擎中变量的结构体如下:

  1. PHP内核变量访问宏

    使用 zval.type = IS_LONG 方式可以设置一个变量的类型,不过这样做不是很合适,因为不能预测PHP以后的版本会发生什么变化,有可能以后版本会把type变量的名字修改成type_gc或其他,那么之前写好的扩展就不能适应这些版本了,为解决这个问题,PHP内核提供一个访问和设置变量类型的方法,具体如下:

    Z_TYPE(zval) 对应zval结构体的实体

    Z_TYPE(&zval) 对应zval结构体的指针

    Z_TYPE(&&zval) 对应zval结构体的二级指针

    可以用以下方式设置变量的类型:Z_TYPE(zval) = IS_LONG,这样,就算以后zval结构体的type成员 变量改名,我们的扩展依然可以使用,与变量的类型一样,变量的值也有相应的访问宏定义如:Z_LVAL(zval) = 10;给变量赋值为10.

  2. 引用计数器与写时复制

    PHP是不支持指针的,为解决希望两个变量指向同一块内存块的问题,PHP内核里使用了引用计数器。

    通过上面zval的结构我们看到,zval结构中有两个成员变量用于引用计数器:

    is_ref: bool,标识变量是否是引用集合

    refcount: 计算指向引用集合的变量个数

    $a = 'this is a variable';

    $b = $a;

    上面的代码创建了两个变量$a,$b,在 PHP7.0 里面在PHP内核中会创建两个变量zval窗口来保存它们,变量b硬拷贝了一份a的值,所以现在$a对应的zval容器的is_ref为FALSE,refcount为1.但在 PHP5.6版本 (及以前?),a的is_ref为FALSE容易理解,因为b并没有对a进行引用,但此时a的refcount为2,这就是因为PHP5.6版本(及以前?)写时复制的机制(copy on write),我用PHP7.0和PHP5.6测试结果证明如此。

    定时复制是一个解决内在利用的方法,值相同时不创建新的内存来保存新的变量,而是把新的变量引用到旧的变量的内存地址,只有在变量的值不同时才进行内存的复制。其实定时复制也是一种引用,不过这种引用会受变量的值的改变而破坏罢了。

    当显式的让一个变量引用另一个变量的时候,变量的is_ref字段会设置为1,表示此变量被引用,另外引用计数器也相应加1.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn