php 变量引用与变量销毁机制详细介绍


Posted in PHP onDecember 05, 2016

php 变量引用与变量销毁机制

在php中,符号”&”表示引用。

1、看看不引用的情况是这样子:

$a = “hello world”;//定义一个变量,下面赋值给$b
$b = $a;//这一步没有在$a之前加符号&,像这样子”$b= & $a”。没有加&,实际上原理是会将变量$a复制拷贝一份,也就是内存中重新申请一个地址存储变量$b了

ps:在php中,使用”=”直接赋值,其实就是拷贝一份右边的变量给b,会生成一份内存空间,结果可能是同样的内容在内存中两份。在有些关于php性能方面提到,这样子会多占有内存空间。不过我接触中,大部分人没怎么注意,其实一般应用这样子用产生的显著差异并不明显。不会看到什么效果,其实我本人也没经常使用&进行引用,呵呵。只是我觉得,深入了解里面的实现原理,非常有必要。我喜欢关注原理性的东西。 

2、使用符号&进行引用

$a = “hello world”;
$b = & $a;

使用引用,php引擎不会拷贝一份变量,其实就是将指针指向了$a在内存中的地址,$b中就是保存了这个指针。
所以使用引用的时候,把$b的值改变,$a也会跟着改变

比如:

$a = “hello world”;
$b = & $a;
$b = “test new value”;//把b的值改掉,a的值也会跟着改变
echo $a;//输出test new value,因为改变了b的值也会改变a的值。
=====================================
经常在定义函数的时候看到像这样的情况:
function test (& $param)
{
//函数定义的内容
$param++;
}

解释:$param前面带有引用,所以传入进来的参数并不会在内存中拷贝一份,而是直接对原来的内存空间进行引用。所以:如果里对使用符号&传入进来的变量值进行修改了,那么也会改变原来的内存空间中的值。

做个测验如下:

$k = 8;
test($k);
echo $k;//结果$k的值被函数里面改变了,输出9。
还会经常看到这样子调用函数:
$return = & test_func();

前面了解到php引擎的机制是:=会把右边的内容拷贝一份给予左边的变量。所以使用&就是将函数的结果不会进行拷贝一份,实际上我的理解是把指针给了左边的变量。

什么是指针,以前学c语言中的概念。我的理解是就是:指针,指针,指向针(指南针,呵呵)。把指针看成是一个内存的地址容易理解点,计算机就知道去内存什么位置找数据了吧。这是浅显的理解,深入的我不会,呵呵。

总结:使用引用是为了减少内存资源的占用。

 php手册中对引用的解释如下:

在 PHP 中引用意味着用不同的名字访问同一个变量内容。这并不像 C 的指针,替代的是,引用是符号表别名。注意在 PHP 中,变量名和变量内容是不一样的,因此同样的内容可以有不同的名字。最接近的比喻是 Unix 的文件名和文件本身——变量名是目录条目,而变量内容则是文件本身。引用可以被看作是 Unix 文件系统中的 hardlink。

 3、销毁变量的时候。并不会改变原来的值。

试验:$b = & $a;

既然改变$b的值,$a的值也跟着改变,假如把$b销毁掉(内存中不占用空间了,不是null,也不是值为””),$a的值是不是也会跟着被删掉呢?

其实国外有本php方面的书中专门提到了这个机制。2年前看的。不是很记得了。原则是就是删除变量的时候,会自动拷贝。
其实这样子,就是为了避免把$b给删掉,造成把$a也给删掉的问题。

<?php
$a = 'd';
$b = & $a;
$b = 8;//因为是引用了,所以把b的值改掉,a的值也跟着改为8了。
var_dump($b,$a);
unset($b);//调用unset删除b变量,a变量不会删除
var_dump($b,$a);//输出null和8
?>

调用unset删除$b变量的时候,php引擎从变量符号表中发现:我要删除的变量$b原来是引用了变量$a,这不好删除啊,因为一删除导致$a变量也没了,所以就先把$a变量拷贝一份后在删除$b变量。

关于php符号表:其实我的理解是,运行中所有变量名称都记录在里面,php来维护,具体的数据当然是存储在内存中,php就是根据这个符号表去回收没有用到的变量空间的,释放内存空间)。去看看php的垃圾回收机制(释放不再使用的内存空间),就是根据符号表进行的。

例子

<?php
$long="big_long_variable_name";
$$long="PHP";   /* 用存放在变量$long里的字符串作为新变量的变量名,等同于$big_long_variable_name="PHP"; */
$short=& $big_long_variable_name; /* 取变量$big_long_variable_name的值赋给变量$short,此时$short的值为"PHP",等同于$short=& $$long; */
print "01 /$short is $short.";  /* "/$"是转义序列,表示输出一个美元符号$,下同。本语句的作用是输出:01 $short is PHP. */
print "02 Long is $big_long_variable_name."; /* 输出:02 Long is PHP. */
?>
<br />
<br />
<?php $big_long_variable_name.=" rocks!"; /* 重新对$big_long_variable_name赋值。重新赋值过程中,由于在$big_long_variable_name的后面添加了.(点号),因而变量$big_long_variable_name此时的值应为原值("PHP")+新值(" rocks!"),即变量$big_long_variable_name当前完整的值为"PHP rocks!"。下同。*/
print "03 /$short is $short";  /* 输出:03 $short is PHP rocks! */
print "04 Long is $big_long_variable_name"; /* 输出:04 Long is PHP rocks! */
?>
<br />
<br />
05 $short is PHP rocks!
06 Long is PHP rocks!
<br />
<br />
<?php $short.="Programming $short";  /* 重新对变量$short赋值。由于在$short后面添加了.(点号),因此请参考上例分析$short的值。*/
print "07 /$short is $short";  /* 输出:07 $short is PHP rocks!Programming PHP rocks! */
print "08 Long is $big_long_variable_name"; /* 由于变量$short被重新赋值为Programming PHP rocks!,因而变量$big_long_variable_name的值也与$short一同被改变为"PHP rocks!Programming PHP rocks!"。本语句输出:08 Long is PHP rocks!Programming PHP rocks!注意,如果是对具有相同值的一个变量进行销毁unset( ),则另一个变量不适用于此种情况,即不会随之被一同销毁。*/
?>
<br />
<br />
09 $short is Programming PHP rocks!
10 Long is Programming PHP rocks!
<br />
<br />
<?php $big_long_variable_name.="Web Programming $short"; /* 变量$big_long_variable_name被重新赋值,此时它完整的值应为PHP rocks!Programming PHP rocks!Web Programming PHP rocks!Programming PHP rocks!。变量$short的值此时与变量$big_long_variable_name一致。请分别参考第5处、第10处注释进行分析。*/
print "11 /$short is $short";   /* 输出:11 PHP rocks!Programming PHP rocks!Web Programming PHP rocks!Programming PHP rocks! */
print "12 Long is $big_long_variable_name";
?>
<br />
<br />
<?php
unset($big_long_variable_name);  /* 用unset( )销毁变量$big_long_variable_name,变量$short不会因此受到任何影响。*/
print "13 /$short is $short";  /* 虽然销毁了变量$big_long_variable_name,但$short没有受到影响,它的值仍是最近一次被赋予的PHP rocks!Programming PHP rocks!Web Programming PHP rocks!Programming PHP rocks! */
print "14 Long is $big_long_variable_name."; /* 变量$big_long_variable_name已被销毁,故而无值。输出:14 Long is. */
snow;                  
?>
<br />
<br />
<?php $short="No point TEST1";  /* 重新对变量$short赋值。由于这次没有在$short后面添加.(点号),因此$short当前的值为"No point TEST1"。*/
print "15 /$short is $short.";  /* 输出:15 $short is No point TEST1. */
$short="No point TEST2 $short";  /* 重新对变量$short赋值。没在$short的后面添加.(点号),但引用了它自身最近一次的值"No point TEST1"。*/
print "16 /$short is $short.";  /* 输出:16 $short is No point TEST2 No point TEST1. */

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

PHP 相关文章推荐
ADODB的数据库封包程序库
Dec 31 PHP
php提示Failed to write session data错误的解决方法
Dec 17 PHP
PHP制作百度词典查词采集器
Jan 29 PHP
php中header跳转使用include包含解决参数丢失问题
May 08 PHP
PHP中Restful api 错误提示返回值实现思路
Apr 12 PHP
php使用pear_smtp发送邮件
Apr 15 PHP
PHP将MySQL的查询结果转换为数组并用where拼接的示例
May 13 PHP
php微信公众平台开发之微信群发信息
Sep 13 PHP
php使用ftp远程上传文件类(完美解决主从文件同步问题的方法)
Sep 23 PHP
PHP实现求解最长公共子串问题的方法
Nov 17 PHP
Docker搭建自己的PHP开发环境
Feb 24 PHP
浅析PHP中的 inet_pton 网络函数
Dec 16 PHP
[原创]php实现 data url的图片生成与保存
Dec 04 #PHP
php 魔术常量详解及实例代码
Dec 04 #PHP
深入浅出讲解:php的socket通信原理
Dec 03 #PHP
thinkphp实现分页显示功能
Dec 03 #PHP
thinkphp jquery实现图片上传和预览效果
Jul 22 #PHP
详解PHP用substr函数截取字符串中的某部分
Dec 03 #PHP
微信公众平台开发(五) 天气预报功能开发
Dec 03 #PHP
You might like
Thinkphp实现MySQL读写分离操作示例
2014/06/25 PHP
PHP从FLV文件获取视频预览图的方法
2015/03/12 PHP
PHP实现活动人选抽奖功能
2017/04/19 PHP
PHP通过文件路径获取文件名的实例代码
2018/10/14 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
2019/12/20 PHP
另类调用flash无须激活的方法
2006/12/27 Javascript
脚本安需导入(装载)的三种模式的对比
2007/06/24 Javascript
jquery 图片 上一张 下一张 链接效果(续篇)
2010/04/20 Javascript
js判断屏幕分辨率的代码
2013/07/16 Javascript
用javascript判断IE版本号简单实用且向后兼容
2013/09/11 Javascript
JS获取当前脚本文件的绝对路径
2016/03/02 Javascript
JS onkeypress兼容性写法详解
2016/04/27 Javascript
浅析JSONP技术原理及实现
2016/06/08 Javascript
关于动态执行代码(js的Eval)实例详解
2016/08/15 Javascript
js获取json中key所对应的value值的简单方法
2020/06/17 Javascript
Vue2.0 UI框架ElementUI使用方法详解
2017/04/14 Javascript
js中Object.defineProperty()方法的不详解
2018/07/09 Javascript
vue前端和Django后端如何查询一定时间段内的数据
2021/02/28 Vue.js
python高并发异步服务器核心库forkcore使用方法
2013/11/26 Python
Python实现统计给定列表中指定数字出现次数的方法
2018/04/11 Python
python连接mongodb密码认证实例
2018/10/16 Python
Python对Excel按列值筛选并拆分表格到多个文件的代码
2019/11/05 Python
python jenkins 打包构建代码的示例代码
2019/11/29 Python
pymysql之cur.fetchall() 和cur.fetchone()用法详解
2020/05/15 Python
GUESS Factory加拿大:牛仔裤、服装及配饰
2019/09/20 全球购物
俄罗斯小米家用电器、电子产品和智能家居商店:Poood.ru
2020/04/03 全球购物
了解AppleTalk协议吗
2014/04/01 面试题
酒吧员工的岗位职责
2013/11/26 职场文书
网络信息管理员岗位职责
2014/01/05 职场文书
给酒店员工的表扬信
2014/01/11 职场文书
聚美优品广告词改编
2014/03/14 职场文书
党员教师自我剖析材料
2014/09/29 职场文书
财产分割协议书范本
2014/11/03 职场文书
2014小学二年级班主任工作总结
2014/12/05 职场文书
投资申请报告
2015/05/19 职场文书
优秀团员主要事迹材料
2015/11/05 职场文书