php内核中的变量

php是弱类型语言,它可以保存任何的数据类型。但是php是使用c语言编写的,而c语言是强类型语言。每个变量都有固定的类型,不能随意改变变量的类型。

在zend/zend.h中,查看结构体:

zval结构体就是通常用到的php变量在内核总的表示形式,在zval结构体中,可以看到四个成员变量,分别是:

zvalue_value value:变量的值,php变量的值就保存在这里。

zend_uint refcount:变量引用数,变量引用计算器。

zend_uchar type:变量的类型。

zend_uchar  is_ref:变量是否被引用。

zval结构体的value成员变量是zvalue_value联合体,php能够保持任何的结构类型就因为这个联合体。从zvalue_value联合体的成员变量中可以看到,不同的类型会保存到不同的成员变量中,这样就实现了php变量可以存储任何数据类型。例如,当变量是整数类型时,会保存到value的lval成员变量中,而当变量的类型是字符串时,又回保存到value的str成员变量中。

以上是解决了php变量可以保存任意类型的问题,但是zend引擎是怎么知道这个变量保存的是什么类型呢,在zval结构中有个type成员变量,这个成员变量就是保存一个php变量的类型。

我们都知道,php是不支持指针的,但是如果希望两个变量同事指向同一块内存怎么办?为了解决这个问题,php内核中使用了引用计数器。

zval结构中有两个成员变量用于引用计数器:

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

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

<?php

$a = "this is leju";

?>

一个zval结构的实体称为zval容器,在php语言层创建一个变量就会相应的在php内核中创建一个zval容器。因为上面的代码创建了一个变量$a,所以在PHP内核中会创建一个zval容器。又因为这个变量不是一个引用,所以zval容器的is_ref等于false,并且refcount等于1.

<?php

$a = "this is leju";

$b = $a;

?>

上面这段代码中创建了两个变量  $a和$b,所以php内核中会创建两个zval容器来保存它们,变量b被赋予变量a的值,由于变量b并不是引用a,所以变量a的is_ref变量的值是false,但是使用xdebug打印变量a的话,会发现refcount等于2,这是为啥呢?

首先来了解下php写时复制(copy on write)机制。

写时复制是一个解决内存复用的方法,例如上面的代码,如果简单的把a的值赋值给b,那么就又两个 this is leju 字符串的复制,这样不利于内存的复用,因为完全可以使用一个 this is leju的字符串的复制完成工作,所以简单的赋值是非常耗内存的,写时复制就是为了解决这种问题而创造的,那什么是写时复制呢,就是当变量的值改变时才进行的内存的复制。

当将变量a的值赋值给变量b时,变量a的refcount增加1,所以这时候变量a和变量b是指向同一内存块的,当改变变量a的值时,发现refcount的值变回1,所以这个时候变量a和变量b指向不同的内存块,这就是写时复制机制,就是两个指向同一内存块的变量,当其中一个变量的值发生变化,才会另外创建一个内存块去保存新的值,其实写时复制也是一种引用,只不过这种引用会受变量值的改变而破坏罢了。

如果显示的引用变量,即$b = &a;变量的is_ref字段会设置1,表示此变量被引用,另外引用计数器(refcount)也相应的加1,在php内核中通过以下代码判断是否复制变量:

if ((*varval)->is_ref || (*varval)->refcount < 2){

return *varval;

}

推荐一本书,《PHP核心技术与最佳实践》 非常好看~

时间: 2024-08-04 11:51:31

php内核中的变量的相关文章

【PHP内核学习】变量和数据类型

|=-----------------------------------------------------------------------=| |=---------------------=[ PHP内核中的变量和数据类型]=--------------------=| |=-----------------------------------------------------------------------=| |=--------------------------=[ by

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

PHP中的变量可以保存任何的数据类型,这是因为它是弱类型语言.但php是用C语言编写的,C语言是强类型语言,每个变量都有固定的类型,不能随意改变变量的类型(可以通过强制类型转变,不过有可能出现问题),在zend引擎中是怎样可以做到一个变量保存任何类型的呢? 在zend/zend.h头文件中,会发现下面的结构体: typedef struct _zval_struct zval; typedef union _zvalue_value { long lval; double dval; struc

Linux内核中的哈希表

Author:tiger-john Time:2012-12-20mail:[email protected]Blog:http://blog.csdn.net/tigerjb/article/details/8450995 转载请注明出处. 前言: 1.基本概念: 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表.

PHP内核探索之变量(4) - 数组操作

上一节(PHP内核探索之变量(3)- hash table),我们已经知道,数组在PHP的底层实际上是HashTable(链接法解决冲突),本文将对最常用的函数系列-数组操作的相关函数做进一步的跟踪. 本文主要内容: PHP中提供的数组操作函数 数组操作函数的实现 结语参考文献 一.PHP中提供的数组操作函数 可以说,数组是PHP中使用最广泛的数据结构之一,正因如此,PHP为开发者提供了丰富的数组操作函数(参见http://cn2.php.net/manual/en/ref.array.php

Linux内核中的jiffies及其作用介绍及jiffies等相关函数详解

在LINUX的时钟中断中涉及至二个全局变量一个是xtime,它是timeval数据结构变量,另一个则是jiffies,首先看timeval结构struct timeval{time_t tv_sec; /***second***/susecond_t tv_usec;/***microsecond***/}到底microsecond是毫秒还是微秒?? 1秒=1000毫秒(3个零),1秒=1000 000微秒(6个零),1秒=1000 000 000纳秒(9个零),1秒=1000 000 000

shell中的变量及shell条件判断

Shell 基础之变量和条件判断 一.shell概述 1.shell概述: shell是一个命令行的解释器,为用户提供了一个向Linux内核发送请求以便运行程序的界面系统及程序,用户可以用shell来启动.挂起.停止甚至编写一些程序,shell还是一个功能强大的编程语言,shell是解释性的脚本语言,在shell中可以直接调用Linux命令. 2.shell脚本的用途 (1)自动化常用的命令 (2)执行系统管理和故障排除 (3)执行简单的应用程序 (4)处理文本或文件 3.shell的分类 (1

向linux内核中添加外部中断驱动模块

本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内核中添加外部中断驱动模块.7.完整驱动程序代码.linux的内核版本为linux2.6.32.2. 一.linux模块的框架以及混杂设备相关知识 1.内核模块的框架如下图所示,其中module_init()(图中有误,不是modules_init)只有在使用insmod命令手动加载模块时才会被调用,

Linux内核中的通用双向循环链表

开发中接触Linux越来越多,休息放松之余,免不了翻看翻看神秘的Linux的内核.看到双向链表时,觉得挺有意思的,此文记下. 作为众多基础数据结构中的一员,双向循环链表在各种“教科书”中的实现是相当的标准和一致的. 大概就是下面这个样子: 1 typedef struct node_tag{ 2 //T data; 3 struct node_tag *prev; 4 struct node_tag *next; 5 }node; 当你需要某种类型的链表时,把数据成员之类的往节点里塞就是了.比如

PHP内核探索之变量(1)Zval

作为数据的容器,我们常常需要跟变量打交道,不管这个变量是数字.数组.字符串.对象还是其他,因而可以说变量是构成语言的不可或缺的基础.本文是PHP内核探索之变量的第一篇,主要介绍zval的基本知识,包括如下几个方面的内容: Zval的基本结构 查看zval的方法:debug_zval_dump和xdebug Zval的原理,COW等 由于写作仓促,难免会有错误,欢迎指出. 一.Zval的基本结构 Zval是PHP中最重要的数据结构之一(另一个比较重要的数据结构是hash table),它包含了PH