php引用计数与变量引用
每个php5.5变量都存储在一个叫做zval的变量容器中。
一个zval变量容器,除了包含变量的类型与值外,还包含两个字节的额外信息:
1、第一个是“is_ref”,是个bool型,用来标识这个变量是否属于引用集合(reference set),若属于则其值为1,否则为0。
有个这个变量php引擎就能够将普通变量与引用变量区分开来。
2、第二个是“refcount”,用来表示指向这个zval变量(符号)的个数。每个符号都有作用域(scope),那些主脚本和函数或者方法也都有作用域。
所有的符号都存在一个符号表中。
当一个变量被赋值一个常量值时,就会生成一个zval变量容器,如下例:
<?php
$a = "Hello world";
?>
这个时候执行以下程序得到$a变量指向zval容器中的is_ref与refcount值
<?php
$a = "Hello world";
print_r(xdebug_debug_zval('a'));
?>
a: (refcount=1, is_ref=0)='Hello world'
下面,我们进行如下实验,来探讨引用赋值与普通赋值。
首先,使$b指向$a,查看is_ref、 refcount,如下:
<?php
$a = "Hello world";
$b = $a;
print_r(xdebug_debug_zval('a'));
print_r(xdebug_debug_zval('b'));
?>
a: (refcount=, is_ref=)='Hello world'
b: (refcount=, is_ref=)='Hello world'
让$b引用$a,查看is_ref refcount,如下
<?php
$a = "Hello world";
$b = &$a;
print_r(xdebug_debug_zval('a'));
print_r(xdebug_debug_zval('b'));
?>
a: (refcount=, is_ref=)='Hello world'
b: (refcount=, is_ref=)='Hello world'
从上我们可以分析出,当有变量引用相应zval容器时,is_ref为1。
我们进一步分析,我们把$b 引用$a,$c指向$a,如下
<?php
$a = "Hello world";
$b = &$a;
$c = $a; print_r(xdebug_debug_zval('a'));
print_r(xdebug_debug_zval('b'));
print_r(xdebug_debug_zval('c'));
?>
打印结果如下
a: (refcount=, is_ref=)='Hello world'
b: (refcount=, is_ref=)='Hello world'
c: (refcount=, is_ref=)='Hello world'
可见,这个时候php5.5引擎为$c重新建立了一个zval容器,容器中的数据类型、值与$a指向的容器中的完全相同,不同的是其refcount与is_ref的值。
因此,我们可以看出,php5.5的zval容器中的is_ref变量要么标识引用集合,要么标识普通集合,当两者都有时,他将克隆zval容器,来解决冲突问题。
总结:
1、在php5.5以后,“变量赋值”都是指向赋值,即将某个变量指向特定的zval容器。
2、“变量引用”则是将变量与变量进行绑定,若绑定的变量中有一个变量改变了指向,则相互绑定的其他变量的指向也随着改变。
若变量重新引用变量,则其原来的变量绑定解除,转而绑定新的变量。如下代码:
<?php
function foo(&$var)
{
$var =& $GLOBALS["baz"];
}
foo($bar);
?>
这将使 foo 函数中的 $var 变量在函数调用时和 $bar 绑定在一起,但接着又被重新绑定到了 $GLOBALS["baz"] 上面。不可能通过引用机制将 $bar 在函数调用范围内绑定到别的变量上面,因为在函数 foo 中并没有变量$bar(它被表示为 $var,但是 $var 只有变量内容而没有调用符号表中的名字到值的绑定)。可以使用引用返回来引用被函数选择的变量。
--------------------------------------------------------------------------------
最后,前段时间利用手头的日本VPS搭建了一个google代理,访问速度还行,分享给大家:
谷歌guge不行了,就打119
谷歌:guge119.com 谷歌学术:scholar.guge119.com
php引用计数与变量引用的更多相关文章
- swift详解之九---------------自动引用计数、循环引用
自动引用计数.循环引用(这个必须理解,必须看) 注:本文详细介绍自动引用计数,以及各种循环引用问题.一网打尽! 1. 自动引用计数原理 Swift 使用ARC机制来跟踪和管理你的内存,一般情况下,Sw ...
- std::shared_ptr 和 std::weak_ptr的用法以及引用计数的循环引用问题
在std::shared_ptr被引入之前,C++标准库中实现的用于管理资源的智能指针只有std::auto_ptr一个而已.std::auto_ptr的作用非常有限,因为它存在被管理资源的所有权转移 ...
- oc引用计数原理-引用计数相关变化
http://blog.csdn.net/null29/article/details/71191044 在 32 位环境下,对象的引用计数都保存在一个外部的表中,每一个对象的 Retain 操作,实 ...
- 从urllib2的内存泄露看python的GC python引用计数 对象的引用数 循环引用
这里会发现上述代码是存在内存泄露,造成的原因就是lz与ow这两个变量存在循环引用,Python 不知道按照什么样的安全次序来调用对象的 __del__() 函数,导致对象始终存活在 gc.garbag ...
- 【Python】引用计数
一.概述 要保持追踪内存中的对象,Python使用了引用计数这一简单的技术. 二.引用计数的增减 2.1 增加引用计数 当对象被创建并(将其引用)赋值给变量时,该对象的引用计数被设置为1. 对象的引用 ...
- Objective-C内存管理之-引用计数
本文会继续深入学习OC内存管理,内容主要参考iOS高级编程,Objective-C基础教程,疯狂iOS讲义,是我学习内存管理的笔记 内存管理 1 内存管理的基本概念 1.1 Objective-C中的 ...
- 第3月第2天 find symbolicatecrash 生产者-消费者 ice 引用计数
1.linux find export find /Applications/Xcode.app/ -name symbolicatecrash -type f export DEVELOPER_DI ...
- Andorid Binder进程间通信---Binder本地对象,实体对象,引用对象,代理对象的引用计数
本文參考<Android系统源码情景分析>,作者罗升阳. 一.Binder库(libbinder)代码: ~/Android/frameworks/base/libs/binder --- ...
- 初步swift语言学习笔记6(ARC-自己主动引用计数,内存管理)
笔者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/31824179 转载请注明出处 假设认为文章对你有所帮助.请通过留言 ...
随机推荐
- UVA11456--dp,LIS
这道题是个不错的dp题,可以放在区域赛签到题或者铜牌题. 这题希望火车序列最长,我们可以想到,如果一辆车ai如果能被放上去,先不管之前放上了多少辆车,以及这辆车是什么时候放上去的,但是我们可以确定的是 ...
- Mysql--mysqldump命令 备份数据库
mysqldump命令用来备份数据库. mysqldump命令在DOS的[url=file://\\mysql\\bin]\\mysql\\bin[/url]目录下执行. 1) 导出整个数据库(导出文 ...
- Dalvik虚拟机Java堆创建过程分析
文章转载至罗升阳CSDN社区博客,原地址: http://blog.csdn.net/luoshengyang/article/details/6557518 近年来,手机移动平台越来越火爆.打开自己 ...
- 配置linux中文
1.~/.bash_profile文件添加一下内容并执行source ~/.bash_profile export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK 2./etc ...
- 关于css3的rgba
在rgba之前,我们应该知道rgb.它就是红色R+绿色G+蓝色B.那rgba是什么?简单的说就是在rgb的基础之上加上一个通道alpha.他的语法如下: r 红色值.正整数(0~255) | 百 ...
- asp.net读取文件
context.Response.ContentType = "text/html"; string fullpath = context.Server.MapPath(" ...
- 《第一行代码》学习笔记29-内容提供器Content Provider(2)
1.查询操作: if (cursor != null) { while (cusor.moveToNext()) { String column1 = cursor.getString(cursor. ...
- 浅谈Block传值-匿名函数(代码块)
block传值是从后往前传值---代理也是 // 使用block时, 不能访问self, 也不能直接访问属性, self.属性, 用self调用方法; 只要这样做了, block都会对其强引用一份, ...
- Python提取图片的ROI
图像处理经常需要提取图片的ROI,本文使用Python提取图片的ROI. 使用的Module是PIL (Pillow),一个图像处理库,用到的函数为类 Image 中的 crop 方法. 函数原型为: ...
- IT编程培训,线上线下,孰优孰劣
现在Java培训机构确实参差不齐,主要有在线培训和线下培训两大类: 1,虚拟和现实的区别:不论视觉,听觉,体验上在线教学都不如线下教学. 2,学费问 题:在线教学由于成本低,不受地域,教学设备限制一般 ...