每个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引用计数与变量引用的更多相关文章

  1. swift详解之九---------------自动引用计数、循环引用

    自动引用计数.循环引用(这个必须理解,必须看) 注:本文详细介绍自动引用计数,以及各种循环引用问题.一网打尽! 1. 自动引用计数原理 Swift 使用ARC机制来跟踪和管理你的内存,一般情况下,Sw ...

  2. std::shared_ptr 和 std::weak_ptr的用法以及引用计数的循环引用问题

    在std::shared_ptr被引入之前,C++标准库中实现的用于管理资源的智能指针只有std::auto_ptr一个而已.std::auto_ptr的作用非常有限,因为它存在被管理资源的所有权转移 ...

  3. oc引用计数原理-引用计数相关变化

    http://blog.csdn.net/null29/article/details/71191044 在 32 位环境下,对象的引用计数都保存在一个外部的表中,每一个对象的 Retain 操作,实 ...

  4. 从urllib2的内存泄露看python的GC python引用计数 对象的引用数 循环引用

    这里会发现上述代码是存在内存泄露,造成的原因就是lz与ow这两个变量存在循环引用,Python 不知道按照什么样的安全次序来调用对象的 __del__() 函数,导致对象始终存活在 gc.garbag ...

  5. 【Python】引用计数

    一.概述 要保持追踪内存中的对象,Python使用了引用计数这一简单的技术. 二.引用计数的增减 2.1 增加引用计数 当对象被创建并(将其引用)赋值给变量时,该对象的引用计数被设置为1. 对象的引用 ...

  6. Objective-C内存管理之-引用计数

    本文会继续深入学习OC内存管理,内容主要参考iOS高级编程,Objective-C基础教程,疯狂iOS讲义,是我学习内存管理的笔记 内存管理 1 内存管理的基本概念 1.1 Objective-C中的 ...

  7. 第3月第2天 find symbolicatecrash 生产者-消费者 ice 引用计数

    1.linux find export find /Applications/Xcode.app/ -name symbolicatecrash -type f export DEVELOPER_DI ...

  8. Andorid Binder进程间通信---Binder本地对象,实体对象,引用对象,代理对象的引用计数

    本文參考<Android系统源码情景分析>,作者罗升阳. 一.Binder库(libbinder)代码: ~/Android/frameworks/base/libs/binder --- ...

  9. 初步swift语言学习笔记6(ARC-自己主动引用计数,内存管理)

    笔者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/31824179 转载请注明出处 假设认为文章对你有所帮助.请通过留言 ...

随机推荐

  1. poj 2049 Let it Bead(polya模板)

      Description Cannery Row percent of the target audience insists that the bracelets be unique. (Just ...

  2. 基础总结篇之中的一个:Activity生命周期

    子曰:溫故而知新,能够為師矣.<論語> 学习技术也一样,对于技术文档或者经典的技术书籍来说,指望看一遍就全然掌握,那基本不大可能,所以我们须要常常回过头再细致研读几遍,以领悟到作者的思想精 ...

  3. [转载]aptitude与apt-get的区别和联系

    转自 http://www.cnblogs.com/yuxc/archive/2012/08/02/2620003.html 命令 下面将要介绍的所有命令都需要sudo!使用时请将“packagena ...

  4. AIX 常用命令和知识

      BOOTLIST:#bootlist -m normal -o (查看bootlist)#bootlist -m normal (设置bootlist为空,谁要在我机器上执行我就要哭了)#boot ...

  5. DEV GridControl 根据单元格值改变背景色

    GridControl 根据单元格值改变背景色(需要用到CustomDrawCell事件) 方法1: private void gdvClient_CustomDrawCell(object send ...

  6. C#语法糖: 扩展方法(常用)

    今天继续分享C#4.0语法糖的扩展方法,这个方法也是我本人比较喜欢的方法.大家先想想比如我们以前写的原始类型不能满足现在的需求,而需要在该类型中添加新的方法来实现时大家会怎么做.我先说一下我没有学习到 ...

  7. 【原创】C++中对象的序列化

    1.对象序列化 对象的序列化是指将对象的状态信息转换为可以存储或者传输的形式的过程.对象的反序列化是与序列化相反的过程. 在序列化期间,对象将其当前的状态写入到临时或者永久性的存储区,可以通过从存储区 ...

  8. [Mac] 使用Mac时的一些技巧

    这篇博客就用来记录自己在使用Mac时学来的一些技巧吧! 1. 如何开启 Sticky key (在屏幕上显示输入的控制键)   就是这个东西啦,就是在视频演示的时候让别人看到自己按了什么控制键. 在s ...

  9. js单例模式

    js实现单例模式,经常使用两种方法,一种是使用构造函数的静态属性中缓存该实例,另一种是将实例包装在闭包中. 第一种实现方式: //静态属性中单例模式 function Universe() { if ...

  10. C语言变量的存储类别

    我们知道,从变量的作用域(即从空间)角度来分,可以分为全局变量和局部变量. 从另一个角度,从变量值存在的作时间(即生存期)角度来分,可以分为静态存储方式和动态存储方式. 静态存储方式:是指在程序运行期 ...