`

深入理解PHP之引用一

    博客分类:
  • php
阅读更多

 

PHP是弱语言,其变量处理的过程是不可见的。

你是否曾经很想知道在变量拷贝的时候,PHP引擎做了什么?

你是否曾经很想知道一个函数是如何以引用的方式返回一个变量?

如果是这样,请您接着向下看。

每门计算机语言都需要一些容器来保存变量数据。在一些语言当中,变量都有特定的类型,如字符串,数组,对象等等。比如C和Pascal就属于这种。而PHP则没有这样的类型。在PHP中,一个变量在某一行是字符串,可能到下一行就变成了数字。变量可以经常在不同的类型间轻易的转化,甚至是自动的转换。PHP之所以成为一个简单并且强大的语言,很大一部分的原因是它拥有弱类型的变量。但是有些时候这也会带来一些有趣的问题。

在PHP内部,变量是存储在一个叫做zval的容器中。它不仅仅包含变量的值,也包含变量的类型。Python和PHP类似,也有一个标签标记变量类型。变量容器中包含一些Zend引擎用来区分是否引用的字段。同时它也包含这个值的引用计数。

变量存储在一个相当于关联数组的符号表中。这个数组以变量名为key,并且指向包含了这些变量的容器。如图1所示:

php-variables-01

引用计数

PHP试着在变量拷贝(如 $a = $b )的时候变得聪明些。“=”也称为赋值操作符。当进行赋值操作时,Zend引擎不会创建一个新的变量窗口,而是增大变量窗口的 refcount 字段,你可以想象一下,当这个变量是一个巨大的字符串或一个巨大 的数组时,这将节约多少的内存。如图2所示,

php-variables-02

第一步: 变量a,包含文本”this is”。默认情况下,引用计数等于1

第二步:将变量$a赋值给$b和$c。这里没有新的变量容器生成,仅仅是每次在变量赋值操作时将refcount加1。因为这里执行了两次赋值操作,所以refcount最后会变成3。

现在,也许你很想知道当变量$c改变时将发生什么。根据refcount的值的不同,它会有两种不同的处理方式。如果refcount等于1,这个变量容器将更新它的值(也许同时会更新它的类型)。如果refcount大于1,将创建一个包含了新值(和类型)的变量容器。如图2所示的第三步,$a变量所在的变量容器的refcount值被减去一,现在refcount的值是2,而新创建的容器的refcount的值为1。当对一个变量使用unset函数时,这个变量所在的容器的refcount值将减去一,如图第4步所示。如果refcount的值少于1,Zend引擎将翻译这个变量容器,如图第5步所示。

 

传递变量给函数(Passing Variables to Functions)

除了所有脚本共用的全局符号表以外,每个用户定义的函数在调用时都会创建一个属于自己的符号表,用来存放它自己的变量。当一个函数被调用后,Zend引擎就会创建一个这样的符号表,当这个函数返回时这个函数表就会被释放。一个函数要么通过return语句返回,要么因为函数结束而返回(译者注:无返回的函数默认会返回NULL)。如图3所示:

 

php-variables-03

图3详细介绍了变量是如何传递给函数的。

第一步,我们将”thisis”赋给变量$a,然后我们将这个变量传递do_something()函数的$s变量。

第二步,你可以看到这与变量赋值的操作是一样的(与我们在前一小节提到的$b = $a类似),只是其存储在不同的符号表(函数符号表),并且引用计数加2,而不是加1。原因是函数栈也包含了这个变量容器的引用。

第三步,当我们赋新值给变量$s,原变量容器的refcount减1,并且创建一个包含了新值的变量容器。

第四步,我们通过return语句返回一个变量。返回的变量从全局符号表中获取一个实体并将其refcount的值增加1.当函数结束时,函数的符号表将被销毁。在销毁的过程中,Zend引擎将遍历符号表中的每个变量,并将其refcount的值减少。当变量容器的refount的值变为0,这个变量容器将会被销毁。如你所见,由于 PHP的引用计数机制,变量容器不是以拷贝的方式从函数返回。如果变量$s在第三步时没有被修改,则变量$a和$b将一直指向相同的变量容器(这个容器的refcount为2)。在这种情况下,语句$a = “this is”将不会创建变量容器的副本。

英文原文地址:http://derickrethans.nl/files/phparch-php-variables-article.pdf

以上只是第一部分的内容,原来看懂很容易,翻译出来相当难。

分享到:
评论

相关推荐

    深入理解PHP内核(一)

    从实践出发,继弱类型变量原理探究后,本文继续带领大家深入理解php内核。  最近,和一个网友交流的时候,给我提了一个非常奇怪的问题。那就是,在一个运算中,加了一个引用之后,发现性能慢了一万倍。在我的脑海...

    深入理解PHP变量的值类型和引用类型

    在PHP中,大部分变量类型,如字符串,整型,浮点,数组等都是值类型的,而类和对象是引用类型,在使用的时候,需要注意这一点。 看到网友在讨论PHP的&符号,要彻底理解它的用法,就有必要讨论一下变量的两种形式。 ...

    十幅图告诉你什么是PHP引用

    您可能感兴趣的文章:PHP引用的调用方法分析深入理解PHP变量的值类型和引用类型PHP中返回引用类型的方法PHP的引用详解PHP中变量引用与变量销毁机制分析深入分析PHP引用(&)PHP对象相互引用的内存溢出实例分析PHP...

    深入了解WordPress.pdf

    中文名: 深入了解WordPress 原名: WordPress In Depth 作者: Bud Smith资源格式: PDF 版本: 插图版 出版社: Que书号: 0789742756发行时间: 2010年02月21日 地区: 美国 语言: 英文 简介: 内容简介: 引用 ...

    深入理解 PHP7 中全新的 zval 容器和引用计数机制

    仔细一想不难发现问题所在:这些文章大多是 PHP5.x 时代的,而 PHP7 发布后,采用了新的 zval 结构,相关的资料也比较贫瘠,所以我结合一些资料做了一个总结, 主要侧重于解释新 zval 容器中的引用计数机制 ,如有...

    深入了解PHP中的Array数组和foreach

    1. 了解数组 PHP 中的数组实际上是一个有序映射。映射是一种把 values 关联到 keys 的类型。详细的解释可参见:PHP.net中的Array数组 。 2.例子:一般的数组 这里,我通过一个简单的例子,并使用图形方式来了解数组...

    (全)传智播客PHP就业班视频完整课程

    函数调用深入理解 函数使用注意事项① 8-22 5.函数使用注意事项② 函数作业布 8-23 1.函数再回顾 自定义函数 8-23 2.位运算① 8-23 3.位运算② 8-23 4.数组介绍 数组的创建 ?榈谋槔? 8-23 5.数组的引用 数组使用...

    史上最全韩顺平传智播客PHP就业班视频,10月份全集

    函数调用深入理解 函数使用注意事项① 8-22 5.函数使用注意事项② 函数作业布 8-23 1.函数再回顾 自定义函数 8-23 2.位运算① 8-23 3.位运算② 8-23 4.数组介绍 数组的创建 ?榈谋槔? 8-23 5.数组的引用 数组使用...

    深入理解PHP类的自动载入机制

    php作者想简单点,最好能引用一个类时,如果当前没有include进来,系统能自动去找到该类,自动引进~ 于是:__autoload()函数应运而生。 通常放在应用程序入口类里面,比如discuz中,放在class_core.php中。 先讲浅显...

    史上最全韩顺平传智播客PHP就业班视频,9月份全集

    函数调用深入理解 函数使用注意事项① 8-22 5.函数使用注意事项② 函数作业布 8-23 1.函数再回顾 自定义函数 8-23 2.位运算① 8-23 3.位运算② 8-23 4.数组介绍 数组的创建 ?榈谋槔? 8-23 5.数组的引用 数组使用...

    PHP和MySQL Web开发第4版pdf以及源码

    12.1 深入理解权限系统 12.1.1 user表 12.1.2 db表和host表 12.1.3 tables_priv表,columns_priv表和procs_priv表 12.1.4 访问控制:MySQL如何使用Grant表 12.1.5 更新权限:修改什么时候生效 12.2 提高MySQL...

    PHP和MySQL WEB开发(第4版)

    12.1 深入理解权限系统 12.1.1 user表 12.1.2 db表和host表 12.1.3 tables_priv表,columns_priv表和procs_priv表 12.1.4 访问控制:MySQL如何使用Grant表 12.1.5 更新权限:修改什么时候生效 12.2 提高MySQL数据库...

    PHP对象递归引用造成内存泄漏分析

    主要介绍了PHP对象递归引用造成内存泄漏分析,是PHP程序设计中需要加以重视的一个bug,并且有助于深入理解PHP运行原理,需要的朋友可以参考下

    PHP中变量引用与变量销毁机制分析

    主要介绍了PHP中变量引用与变量销毁机制,较为深入的分析了PHP中变量的引用机制及其原理以及对应的变量的销毁机制,有助于深入理解PHP程序设计原理,需要的朋友可以参考下

    史上最全传智播客PHP就业班视频课,8月份视频

    函数调用深入理解 函数使用注意事项① 8-22 5.函数使用注意事项② 函数作业布 8-23 1.函数再回顾 自定义函数 8-23 2.位运算① 8-23 3.位运算② 8-23 4.数组介绍 数组的创建 ?榈谋槔? 8-23 5.数组的引用 数组使用...

    从PHP的源码中深入了解stdClass类

    在百度百科中,对于stdClass的定义如下:复制代码 代码如下:stdClass在PHP5才开始被流行。而stdClass也是zend的一个...在其它页面为它赋值时是直接修改,而不是引用一个拷贝。 以上的定义大多数都是正确的,但是一个致

    PHP和MySQL Web开发第4版

    12.1 深入理解权限系统 12.1.1 user表 12.1.2 db表和host表 12.1.3 tables_priv表,columns_priv表和procs_priv表 12.1.4 访问控制:MySQL如何使用Grant表 12.1.5 更新权限:修改什么时候生效 12.2 提高MySQL...

    韩顺平PHP JS JQUERY 所有视频下载种子 货真价实

    函数调用深入理解 函数使用注意事项① 8-22 5.函数使用注意事项② 函数作业布 8-23 1.函数再回顾 自定义函数 8-23 2.位运算① 8-23 3.位运算② 8-23 4.数组介绍 数组的创建 ?榈谋槔? 8-23 5.数组的引用 数组使用...

Global site tag (gtag.js) - Google Analytics