php引用计数器,PHP 引用计数器 通俗版解释_PHP教程

PHP 引用计数器 通俗版解释

概述

最近看PHP中的引用计数器部分,首先被各种绕晕,然后通过看博客和分析后,总结了一个比较通俗的解释,能帮助自己很好地记忆,也希望能帮助到各位读者。这里分享一遍博文,是比较正统的解释:PHP变量之引用(http://hilojack.sinaapp.com/?p=1392)。

建议

研究PHP引用计数器的变化可以通过安装Xdebug扩展来学习,安装后直接调用 xdebug_debug_zval('var') 来看变量 $var的引用计数器情况。

基础知识

谈引用计数器需要对PHP中变量的存储、引用计数的机制有所了解,引用计数当然是节约内存,在不影响语义正确性的前提下,让多个变量符号共享一个内存值空间(又称为变量容器)。引用计数什么时候发生变化:赋值。 赋值又有两种: 值传递赋值和引用赋值。比较难以理解的是引用赋值。引用计数的另一个作用就是指示什么时候可以共用同一空间,什么时候必须进行变量分离(另开辟空间)。

通俗解释

为了便于理解和记忆,本人对赋值中的各种情景给以通俗的解释,不要与现实情况对号入座,

0414454E3-0.gif

& 号是结合,可以相当于结婚,但是PHP中允许多个人一起结婚(即一夫多妻制或一妻多夫制),这个比较变态。 注意结婚必须同居,分居是不行的。除了结婚外还有一种形态叫 合租。合租也是同居,但是没有任何关系,允许多人合租,这个是合情合理的。当然还有一种情况是独居,这个比较容易理解。以下面的例子说明赋值语句与这三种状态对应关系:

情景一:

$a = "a"; // $a 独居, is_ref = 0, refcount = 1;

$b = $a; // $a 与 $b 合租, is_ref = 0, refcount = 2;情景二:

$a = "a"; // $a 独居, is_ref = 0, refcount = 1;

$b = &$a; // $a 与 $b 结婚, is_ref = 1, refcount = 2;上面可以看出, is_ref可以理解为结婚证,=1 表示两个和多个变量是结婚关系, =0没有结婚(可以合租或同居),refcount表示了多少个变量住在一起了,=1表示独居,>1表示多人同居(记住,结婚必须同居,但同居未必是结婚关系)。

下面开始分析赋值时的变量变化关系:

情景一:

$a = "a";  // $a 独居, is_ref = 0, refcount = 1;

$b = $a;   // $a 与 $b 合租, is_ref = 0, refcount = 2;

$va = "b"; // $va 独居, is_ref = 0, refcount = 1;

$vb = $va; // $va 和 $vb 合租, is_ref = 0, refcount = 2;

$a = $va;  // $a是单身,$va也是单身,因此 $a 搬去与 $va 同居,现在$a,$va,$vb三人同居

赋值后:

$a: is_ref = 0, refcount = 3, string = "xyz"

$b: is_ref = 0, refcount = 1, string = "qwe"

$va: is_ref = 0, refcount = 3, string "xyz"

$vb: is_ref = 0, refcount = 3, string "xyz"

情景二:

$a = "a";  // $a 独居, is_ref = 0, refcount = 1;

$b = &$a;   // $a 与 $b 结婚, is_ref = 1, refcount = 2;

$va = "b"; // $va 独居, is_ref = 0, refcount = 1;

$vb = $va; // $va 和 $vb 合租, is_ref = 0, refcount = 2;

$a = $va;  // $a是已婚, $a 不能随便单独搬出去,赋值会使$va的值拷贝给$a,其他关系不变

$a: is_ref = 1, refcount = 2, string = "xyz"

$b: is_ref = 1, refcount = 2, string = "xyz"

$va: is_ref = 0, refcount = 2, string "xyz"

$vb: is_ref = 0, refcount = 2, string "xyz"

情景三:

$a = "a";  // $a 独居, is_ref = 0, refcount = 1;

$b = &$a;   // $a 与 $b 结婚, is_ref = 1, refcount = 2;

$va = "b"; // $va 独居, is_ref = 0, refcount = 1;

$vb = &$va; // $va 和 $vb 结婚, is_ref = 1, refcount = 2;

$a = $va;  // $a是已婚, 与情景二相同,值拷贝,关系不变

赋值后:

$a: is_ref = 1, refcount = 2, string = "xyz"

$b: is_ref = 1, refcount = 2, string = "xyz"

$va: is_ref = 1, refcount = 2, string "xyz"

$vb: is_ref = 1, refcount = 2, string "xyz"

情景四:

$a = "qwe"; // $a 独居, is_ref = 0, refcount = 1;

$b = $a; // $a 与 $b 同居, is_ref = 0, refcount = 2;

$va = "xyz"; // $va 独居, is_ref = 0, refcount = 1;

$vb = &$va; // $va 和 $vb 结婚, is_ref = 1, refcount = 2;

$a = $va; // $a 想与 $va同居(而非结婚),但是$va已婚的,因此 $a只能从$b那里搬出来,重新分配个房子,值与$va一样(术语叫:变量分离);$va和$vb关系不变

赋值后:

$a: is_ref = 0, refcount = 1, string = "xyz"

$b: is_ref = 0, refcount = 1, string = "qwe"

$va: is_ref = 1, refcount = 2, string "xyz"

$vb: is_ref = 1, refcount = 2, string "xyz"

情景五:

$a = "qwe"; // $a 独居, is_ref = 0, refcount = 1;

$b = $a; // $a 与 $b 同居, is_ref = 0, refcount = 2;

$va = "xyz"; // $va 独居, is_ref = 0, refcount = 1;

$vb = $va; // $va 和 $vb 同居, is_ref = 0, refcount = 2;

$a = &$va; // $a 想与 $va结婚,现在$a 和 $va 都是单身但是都有室友了,因此他们各自从原来的地方搬出来,然后分个新房子,值与$va原来的一样

赋值后:

$a: is_ref = 1, refcount = 2, string = "xyz"

$b: is_ref = 0, refcount = 1, string = "qwe"

$va: is_ref = 1, refcount = 2, string "xyz"

$vb: is_ref = 0, refcount = 1, string "xyz"

情景六:

$a = "qwe"; // $a 独居, is_ref = 0, refcount = 1;

$b = $a; // $a 与 $b 同居, is_ref = 0, refcount = 2;

$va = "xyz"; // $va 独居, is_ref = 0, refcount = 1;

$vb = &$va; // $va 和 $vb 结婚, is_ref = 1, refcount = 2;

$a = &$va; // $a 想与 $va 结婚,但是 $va 是已婚的,而 $a 是单身,因此 $a 搬过去和 $va 住,$va 现在有两个配偶:$vb 和 $a

赋值后:

$a: is_ref = 1, refcount = 3, string = "xyz"

$b: is_ref = 0, refcount = 1, string = "qwe"

$va: is_ref = 1, refcount = 3, string "xyz"

$vb: is_ref = 1, refcount = 3, string "xyz"

情景七:

$a = "qwe"; // $a 独居, is_ref = 0, refcount = 1;

$b = &$a; // $a 与 $b 结婚, is_ref = 1, refcount = 2;

$va = "xyz"; // $va 独居, is_ref = 0, refcount = 1;

$vb = $va; // $va 和 $vb 同居, is_ref = 0, refcount = 2;

$a = &$va; // $a 想与 $va 结婚,但是 $a 是已婚的,$va 是单身, 解决办法是 $a 离婚后和 $va 结婚,同时 $va 从与 $vb合租的地方搬出来

赋值后:

$a: is_ref = 1, refcount = 2, string = "xyz"

$b: is_ref = 0, refcount = 1, string = "qwe"

$va: is_ref = 1, refcount = 2, string "xyz"

$vb: is_ref = 0, refcount = 1, string "xyz"

情景八:

$a = "qwe"; // $a 独居, is_ref = 0, refcount = 1;

$b = &$a; // $a 与 $b 结婚, is_ref = 1, refcount = 2;

$va = "xyz"; // $va 独居, is_ref = 0, refcount = 1;

$vb = &$va; // $va 和 $vb 结婚, is_ref = 1, refcount = 2;

$a = &$va; // $a 想与 $va 结婚,但是 $a和$va都是已婚的,谁离婚?$a!,因为是$a主动想和$va结婚,

// $a 离婚后$va住一起,$va 现在有两个配偶:$vb 和 $a

赋值后:

$a: is_ref = 1, refcount = 3, string = "xyz"

$b: is_ref = 0, refcount = 1, string = "qwe"

$va: is_ref = 1, refcount = 3, string "xyz"

$vb: is_ref = 1, refcount = 3, string "xyz"

以上分析了简单变量赋值的各种情形,不包括自引用的情况。概况来讲:

简单赋值 就是同居,需考察等号左侧变量的is_ref(即是否已婚),若 is_ref = 1,则值拷贝,否则考虑左侧便令,能否在不另外分配内存的情形下,与右侧变量共用同一存储空间(同居),此时要考察右侧是否是已婚,若是,则不能同居,变量分离,若右侧变量也是单身,则直接共用同一内存,所有同居者都遵循 COW(写时拷贝)的原则。

引用赋值 就是结合, 需先考察右侧变量的引用情况, 若 is_ref = 1,则直接 refcount ++, 出现多人结合的情况, 若右侧是非引用的(is_ref = 0),那还需考察右侧是否是独居,若是独居,则 左右两个变量共用右侧变量空间,否则右侧变量从原来的地方分离出来和左侧开辟新空间。 只要是引用赋值,那么左侧变量总是要与之前结合的或共用的变量进行分离。

http://www.bkjia.com/PHPjc/875473.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/875473.htmlTechArticlePHP 引用计数器 通俗版解释 概述 最近看PHP中的引用计数器部分,首先被各种绕晕,然后通过看博客和分析后,总结了一个比较通俗的解释,...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/561039.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java流式api,Java 8 中流式API性能基准测试

测试代码package hello.test;import org.openjdk.jmh.annotations.*;import org.openjdk.jmh.runner.Runner;import org.openjdk.jmh.runner.RunnerException;import org.openjdk.jmh.runner.options.Options;import org.openjdk.jmh.runner.options.OptionsBuilder;import jav…

windows c语言 http https检测_C语言编程工具的选择

1.先说说我的故事我是2007年上的大学,一所双一流工科大学。专业是计算机科学与技术。我们计算机专业没有C语言这门课。其他工科专业会学C语言这门课。据我所知,其他的工科专业需要过C语言2级考试。计算机专业不用考2级、3级...这些考试。我们计算机专业学…

PHP 继承新增,php类的扩展和继承用法实例

本文实例讲述了php类的扩展和继承用法。分享给大家供大家参考。具体如下:class Thread{var $topic; //帖子主题var $body; //帖子内容var $date; //帖子发布时间var $author; //帖子作者//函数Thread用于初始化变量等function Thread(){//初始化变量}//函数Send用于…

python的固定有没有固定字符_python每次处理固定个数的字符的方法总结

首先,来看每次处理一个字符的情况,可以有如下方法去实现:方法一:代码如下:>>> a1234567>>> list(a)[1, 2, 3, 4, 5, 6, 7]>>>方法二:代码如下:>>> a1234567>>> for i in…

php 按照laravel5.5,Laravel5.5 综合使用

使用 Laravel5.5 开发一个自动交割的项目,把使用到的开源扩展包及特性整理起来,以供后续使用。一、安装IDE提示工具Laravel IDE Helper 是一个极其好用的代码提示及补全工具,可以给编写代码带来极大的便利。1、安装# 如果只想在开发环境安装请…

usb声卡驱动_iCON ProDrive第三代USB声卡驱动全新发布!

2019年3月,iCON官方发布了一款全球首创——全新一代“ProDrive III”USB声卡驱动,iCON所有系列USB声卡(包括带声卡的MIDI键盘)已全面启用ProDrive III !iCON ProDrive III由iCON的国际工程师团队微调的高品质模拟元件和电路,可同时…

分数小数互换图_重复控制器学习心得(二)——超前环节的分数化和校正因子的引入...

本文仅作为学习记录,欢迎各位提出宝贵建议1、超前补偿环节的分数化在上周我学习了分数阶RC的实现方式,无独有偶,超前补偿环节也可以应用插值的方式来近似分数阶补偿。整数阶超前补偿的弊端主要有二:一、当采样频率和固定频率的比值…

php密码怎么用md5,如何使用PHP使用MD5加密此密码?

下面的代码来自一个用PHP编写的登录脚本.它检查密码的数据库不使用MD5加密密码,但是当登录脚本检查数据库中的密码时,它正在检查原始密码而不加密.我熟悉md5()函数但是如何将其合并到以下内容中:session_start();$username $_POST[username];$password $_POST[password];if (…

python嵩天课后题及答案第二章_课后参考答案-第二章部分习题参考答案

习题21-7题,见教材相关章节内容。8.Job1与Job2同时到达,根据短作业优先算法,这时应该先执行Job2,Job2执行完毕时9.0,系统中有job1与job3两个作业,job3较短,所以先执行job3&#xff0…

java中execquery(),javaee登录界面

首先在此之前我们应该正确安装数据库,以及eclipse(javaee)文件包。1.首先在javaee中建立新的项目2.右键点击WebContent-New-JSP File,新建jsp(动态)文件。(想在哪个文件夹里添加jsp文件,就直接右击文件夹新建,注意一定不要展开文件…

电子工程专业评副高总结_微电子科学与工程专业怎么样?

专业简介080704 微电子科学与工程培养目标:本专业培养德、智、体等方面全面发展,具备微电子科学与工程专业扎实的自然科学基础、系统的专业知识和较强的实验技能与工程实践能力,能在微电子科学技术领域从事研究、开发、制造和管理等方面工…

php预处理获取改变行数,php – 使用MySQLi预处理语句时无法获取行数...

如果要使用mysqli_stmt :: $num_rows(即,检查预准备语句中的行数),则需要在执行预准备语句之后使用$stmt-> store_result(),然后才能检查其数量行.这意味着在我们检查返回的行数之前,结果存储在内存中.$stmt $conn->prepare($sql);$stmt->bind_param(ss,$log_usernam…

vue if判断_vue循环判断

<!DOCTYPE html> <html><head><meta charset"utf-8"><title>条件与循环</title><script src"https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script></head><body><h1>判断示例<…

java的一些题目,一些Java题目

1.String str new String("abc"); 请问定义了几个对象。定义了两个对象&#xff0c;一个"abc", 一个是new String().2.面向对象的东西&#xff1a;abstract & interface的各自的作用&#xff0c;区别。3.面向对象的特征&#xff0c;以及怎么实现的。1…

显示器驱动有什么用_科普一下:电脑显示器用什么接口好,主流接口有哪些?...

如今是新的“视”界&#xff0c;生活中总与各种屏幕打交道&#xff0c;难免会遇到选择视频接线的问题&#xff0c;要想搞清楚这点&#xff0c;我们只要通过了解现今常用的几种视频接线就会有个大致的认识。经常会有一些朋友困扰&#xff0c;电脑显示器用什么接口最好&#xff0…

php-cgi并发,对于php-fpm和cgi,还有并发响应的理解

参考链接&#xff1a;首先搞清楚php-fpm与cgi的关系cgicgi是一个web server与cgi程序(这里可以理解为是php解释器)之间进行数据传输的协议&#xff0c;保证了传递的是标准数据。php-cgiphp-cgi是php解释器&#xff0c;就是上文提到的cgi程序。FastcgiFastcgi是用来提高cgi程序(…

更改应用程序图标_在 Windows 10 version 1903 中查看应用程序是否支持 DPI 感知

在显示屏幕上&#xff0c;每英寸点数(DPI)定义构成面板的每个物理单元的像素数。传统上&#xff0c;显示器每英寸输出 96 个像素。但随着技术的发展&#xff0c;各大公司的产品已经开始增加同一物理空间中的像素数&#xff0c;也就造成了屏幕的 DPI 达到 200 甚至更高&#xff…

python程序分析,用Python编写分析Python程序性能的工具的教程

用Python编写分析Python程序性能的工具的教程来源&#xff1a;中文源码网 浏览&#xff1a; 次 日期&#xff1a;2018年9月2日【下载文档: 用Python编写分析Python程序性能的工具的教程.txt 】(友情提示:右键点上行txt文档名->目标另存为)用Python编写分析Python程序…

tina中信号带宽_关于通频带,3dB带宽,三阶截点和1dB压缩点,截止频率,频率范围,带宽,特征频率(中心频率),截止频率和增益(db)...

1、通频带通频带用于衡量放大电路对不同频率信号的放大能力。由于放大电路中电容、电感及半导体器件结电容等电抗元件的存在&#xff0c;在输入信号频率较低或较高时&#xff0c;放大倍数的数值会下降并产生相移。通常情况下&#xff0c;放大电路只适用于放大某一个特定频率范围…

php+控制器+数据库,Laravel5.1数据库连接、创建数据库、创建model及创建控制器的方法_PHP...

本文实例讲述了Laravel5.1数据库连接、创建数据库、创建model及创建控制器的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;前言&#xff1a;laravel创建数据库&#xff0c;实际可以手动创建&#xff0c;如古老的phpmyadmin 等均可以。一、数据库连接&#xff1a…