PHP 变量知识整理

  • 变量的类型(8种)
    四标量:int float string boolean
    两复合:array object
    两特殊类型:resource NULL

  • 变量的定义
    php是弱类型的语言,意味着不用强制申明该变量的类型就可以使用可用。是动态的语言,说明在运行周期内require 一个文件是会引起函数表动态的改变。

强类型语言
int iNum = 1;
string strNum = '1';

php语言
$num = 1;
$num = '1';
  • Zend Engine
    讨论php变量在内存中的存储之前,理解Zend引擎(Zend Engine)的作用和含义。区分下zend studio,zend studio 是zend 公司开发的一款php的集成开发环境。zend 公司是由开源PHP的缔造者和建筑师Zeev Suraski and Andi Gutmans共同创建。
  • Zend Engine 引擎的来历参考这篇文章
    现在基本都是用的是>= php 5.0 的版本。而在php3.0之前php的运行方式还是边解释边运行.运行效率很受其影响,代码耦合度高,可扩展性也不够好,不利于应付各种各样需求。为此,Zeev Suraski 和 Andi Gutmans 决定重写代码以解决这两个问题,把该项技术的核心引擎命名为 Zend Engine,
    • zend Engine的作用
      PHP实现的核心,提供了语言实现上的基础设施,例如:PHP的语法实现,脚本的编译运行环境, 扩展机制以及内存管理等。(主要特性:Zend 就是把 PHP 的边解释边执行的运行方式改为先进行预编译(Compile),然后再执行(Execute)。)
  • 变量在内核中的存储方式

深入PHP变量存储的详解

php是弱类型语言。这代表着一个变量可以保存任何的数据类型。而php是使用C语言编写的。而C语言是强类型语言(每个变量都有其固定的类型).那么在Zend 引擎中是这样做到一个变量可以保存任何的数据类型的。

zend/zend.h 头文件中的结构体
typedef struct_zval_struct zval;
typedef union_zvalue_value {
    long lval;
    double dval;
    struct{
    char*val;
    int len;
    }str;
    Hashlable *ht;
    zend_object_value obj
}zvalue_value;

struct_zval_struct{
    zvalue_value value; //变量的值(一个zvalue_value联合体)
    zend_uint refcount_gc; //变量引用数 
    zend_uchar type;    //变量的类型
    zend_uchar is_ref_gc;  //是否被引用
};

zval 结构体就是php变量在内核中的表示方式。可以看啊zvalue_value联合体中定义了各种数据类型。不同的类型就会保存到不同的成员变量中,这样就实现了php变量可以存储任何的数据类型。
那么又是如何识别各种数据类型的呢?

  • zend引擎定义了几种变量类型,
#define IS_NULL 0
#define IS_LONG 1
#define IS_DUBLE 2
#define IS_STRING 3
#define IS_ARRAY 4
#define IS_OBJECT 5
#define IS_BOOL 6
#define IS_RESOURCE 7

关注下 array 其实对应了Hashtable(将键映射到相对应的值上)

$a = 1;
$b = $a;

这里 变量 a b 共享同一份zval容器;容器的refcount_gc ++;当增减引用时,这个值也相应的递增和递减,一旦减到零,Zend就会回收该zval。那么这个时候就有必要了解写时复制;当多个变量同时指向一个zval容器,而要修改其中一个变量的时候,就会单独为这个变量创建一个新的zval容器。

  • 变量的释放
    其实看了很多的文章.很肯定的一点是unset()是有作用的,只是对于PHP的回收机制来说,会有多种情况.
情况1$a = 1;
unset($a); // 内存是有释放的

情况2$a = 1;
$b = $a;

unset($a); // 由引用计数器可知,这时候 refcount_gc 只是减一,那么实际上refcount_gc=1 
           // refcount_gc>0 的所以zval容器并没有被注销。

那为什么 循环申明变量和循环销毁变量,内存却不会是原来的大小呢。可以参考鸟叔的文章:深入理解PHP内存管理之谁动了我的内存

  • php HashTable

前面归纳的是变量类型、定义和zval的关系。那么每一个变量是如何和zval联系起来呢,可以参考博主orlion的PHP变量在内存中的存储方式

大概为:变量存储在一个相当于关联数组的 符号表中。这个数组以变量名为key,并且指向包含了这些变量的容器.unset变量的时候 应该是先根据这个符号表找到对应的zval ,refcount_gc –.判断,refcount_gc 是否大于0,再决定是否销毁zval。可以肯定的是符号表中$a的键名是肯定删掉了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值