base php - yaokun123/php-wiki GitHub Wiki

基础知识

为了更好的理解PHP7中zval的实现,我们先来了解下一些基本知识,包括数据类型,变量类型,与变量存储密切相关的堆栈等等基本知识

一、数据类型

在c语言中,基本的数据类型有int,double,long,char以及指针ptr。c语言中,数据类型在不同系统中长度不同。

#include<stdio.h>

int main(){
    printf("char sizeof = %d\n",sizeof(char));         //char sizeof = 1
    printf("int sizeof = %d\n",sizeof(int));           //int sizeof = 4
    printf("long sizeof = %d\n",sizeof(long));         //long sizeof = 8
    printf("char * sizeof = %d\n",sizeof(char *));     //char * sizeof = 8
    printf("void * sizeof = %d\n",sizeof(void *));     //void * sizeof = 8
    return 0;
}

二、结构体

struct test{
    char a;     //1
    int b;      //4
    long c;     //8
    void * d;   //8
    int e;      //4
    char * f;   //8
}

从上面代码来看 整个结构体的大小是1+4+8+8+4+8=33?对吗? 下面来打印计算下:

printf("struct test sizeof = %d\n",sizeof(struct test));        //struct test sizeof = 40

从图上可以看到是40 而不是33,为什么呢?这就要引入另外一个概念,结构体对齐,在我的机器上是按照8自己来对齐的,如下图所示:

三、联合体

union test{
        char a;     //1
        int b;      //4
        long c;     //8
        void * d;   //8
    }

printf("union test sizeof = %d\n",sizeof(union test));        //union test sizeof = 8

联合体是复用了同一块内存,对联合体的成员进行修改会影响其他成员的值,联合体的大小为其最大成员变量的大小。

四、堆栈基本知识

  • 栈区(stack):主要是存储参数、局部变量、维护函数调用关系

  • 堆区(heap):动态内容区域,随时申请和释放

  • 全局区:存储全局和静态变量

  • 字面量区:常量字符串存储区

  • 程序代码区:存储二进制代码

示意图如下:

五、变量类型与实现

PHP中的变量是弱类型的,也实现了如int,float,string,array和object等类型。PHP中的变量都是使用结构体zval表示的。下面我们先来了解下PHP5中的zval。

PHP5的zval(PHP5zval结构体 PHP-5.6.31/Zend/zend.h)

typedef union _zvalue_value {
	long lval;					/* long value 8字节*/
	double dval;				/* double value 8字节*/
	struct {
		char *val;    //8字节
		int len;      //4字节
	} str;                //12字节
	HashTable *ht;				/* hash table value 8字节*/
	zend_object_value obj;    //12字节
	zend_ast *ast;            //8字节
} zvalue_value;                   //16字节

struct _zval_struct {
	/* Variable information */
	zvalue_value value;		/* value 16字节*/
	zend_uint refcount__gc;         //4字节,垃圾回收
	zend_uchar type;	/* active type 1字节*/
	zend_uchar is_ref__gc;  //1字节
};//24字节内存对齐

从上面来看,PHP5时代 对zval的优化都是通过结构映射的方式做的。

PHP7的zval

将下文分析

⚠️ **GitHub.com Fallback** ⚠️