c语言编程笔录

首页 >   > 笔记大全

笔记大全

深入理解PHP7内核之zval

更新时间:2023-10-20

什么是zval?

zval是PHP7中的一个重要概念,其代表Zend Value,是PHP7中的一种数据类型。在PHP7之前,每一个变量在内存中都有一个entry,而PHP7中的每个entry都是由一个zval和一个value pointer组成的。因此,可以说zval是一个中间层,将高级语言的变量类型映射到底层的C语言类型。


    // 初始化一个zval,类型为string,值为hello world
    zval my_string;
    ZVAL_STRING(&my_string, "hello world");

可以看到,使用ZVAL_STRING可以将一个C语言字符串值转换为一个zval,使其可以被PHP7的引擎所使用。

zval的分类

zval可以被分类为两种,一种是值类型,即实际存储数据的类型;另一种是类型信息,即语言级别的类型信息。


    // 定义一个zval,类型为整型,值为42
    zval my_int;
    ZVAL_LONG(&my_int, 42);
    
    // 获取zval的类型和值
    int type = Z_TYPE(my_int);
    long value = Z_LVAL(my_int);

上面的代码中,我们定义了一个zval类型为long,值为42的变量。我们可以使用Z_TYPE宏获取zval的类型,使用Z_LVAL宏获取zval的值。

zval和引用计数器

在PHP7中,引用计数器的概念非常重要,因为它允许PHP7通过智能指针来管理zval的释放和内存的回收。当一个zval被创建时,它的引用计数器会被设置为1,当其他变量引用它时,计数器就会增加。当变量不再需要使用zval时,引用计数器会减少。当计数器减少为0时,zval就可以被释放,内存也就可以被回收了。


    // 给一个变量zval添加一个引用计数器
    zval *my_zval;
    my_zval = emalloc(sizeof(zval));
    ZVAL_LONG(my_zval, 42);
    Z_ADDREF_P(my_zval);

上面的代码中,我们使用了Z_ADDREF_P宏来增加变量zval的引用计数器。这样可以避免在其中一个引用计数器减少到0时,同时另一个变量还需要使用这个zval。

zval的作用

总的来说,zval是PHP7内核的一个重要组成部分,可以将高级语言的变量类型映射到C语言类型。它可以代表各种不同的数据类型,例如整型、字符串、数组等等。在引擎内部,zval使用引用计数器来管理内存的分配和释放。


    // 创建一个数组zval
    zval my_array;
    array_init(&my_array);
    
    // 在数组zval中添加一个字符串元素
    add_next_index_string(&my_array, "hello");
    add_next_index_string(&my_array, "world");
    add_index_long(&my_array, 2, 42);

上面的代码中,我们创建了一个数组类型的zval,并向其中添加了三个元素,其中包括两个字符串和一个整型。这些元素可以是各种不同的数据类型,因此zval可以很好地适应PHP7的灵活性。同时,使用zval也可以避免手动处理内存管理的问题,使得编写PHP7程序变得更为简单。