在 PHP 中引用的意思是用不同的名字访问同一个变量内容与在 C 语言中的指针不同: 例如不能对引用做指针运算, 引用并不是实际的内存地址
注意在 PHP 中, 变量名和变量内容是不一样的, 因此同样的内容可以有不同的名字
在 PHP 中引用允许两个变量指向同一个内容, 例如:
- <?php
- $a = &$b;
- ?>
这意味着 $a 和 $b 指向了同一个变量, 在这里 $a 和 $b 是完全相同的, 并不是 $a 指向了 $b 或相反的, 而是 $a 和 $b 指向了同一个地方
再例如:
- [php] view plain copy print?
- <?
- $a = "ABC";
- $b = &$a;
- echo $a;// 这里输出: ABC
- echo $b;// 这里输出: ABC
- $b= "EFG";
- echo $a;// 这里 $a 的值变为 EFG 所以输出 EFG
- echo $b;// 这里输出 EFG
- ?>
- <?
- $a = "ABC";
- $b = &$a;
- echo $a;// 这里输出: ABC
- echo $b;// 这里输出: ABC
- $b= "EFG";
- echo $a;// 这里 $a 的值变为 EFG 所以输出 EFG
- echo $b;// 这里输出 EFG
- ?>
函数的传址调用 [php] view plain copy print?
- function test(&$a)
- {
- $a = $a+100;
- }
- $b=1;
- echo $b;// 输出1
- test($b); // 这里 $b 传递给函数的其实是 $b 的变量内容所处的内存地址, 通过在函数里改变 $a 的值就可以改变 $b 的值了
- echo "<br>";
- echo $b;// 输出 101
- function test(&$a)
- {
- $a = $a+100;
- }
- $b=1;
- echo $b;// 输出1
- test($b); // 这里 $b 传递给函数的其实是 $b 的变量内容所处的内存地址, 通过在函数里改变 $a 的值就可以改变 $b 的值了
- echo "<br>";
- echo $b;// 输出 101
函数的引用返回 [php] view plain copy print?
- function &test()
- {
- static $b = 0;// 申明一个静态变量
- $b = $b + 1;
- echo $b;
- return $b;
- }
- $a=test();// 这条语句会输出 $b 的值为1
- $a=5;
- $a=test();// 这条语句会输出 $b 的值为 2
- $a=&test();// 这条语句会输出 $b 的值为 3
- $a=5;
- $a=test();// 这条语句会输出 $b 的值为 6
- function &test()
- {
- static $b = 0;// 申明一个静态变量
- $b = $b + 1;
- echo $b;
- return $b;
- }
- $a=test();// 这条语句会输出 $b 的值为1
- $a=5;
- $a=test();// 这条语句会输出 $b 的值为 2
- $a=&test();// 这条语句会输出 $b 的值为 3
- $a=5;
- $a=test();// 这条语句会输出 $b 的值为 6
通过这种方式 $a=test(); 得到的其实不是函数的引用返回, 这跟普通的函数调用没有区别
PHP规定通过 $a=&test(); 方式得到的才是函数的引用返回
至于什么是引用返回呢(PHP手册上说: 引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时) 这句狗屁话害我半天没看懂
用上面的例子来解释就是
$a=test()方式调用函数, 只是将函数的值赋给 $a 而已, 而 $a 做任何改变都不会影响到函数中的 $b
而通过 $a=&test()方式调用函数呢, 他的作用是将 return $b 中的 $b 变量的内存地址与 $a 变量的内存地址指向了同一个地方
即产生了相当于这样的效果($a=&b;) 所以改变 $a 的值也同时改变了 $b 的值所以在执行了
- $a=&test();
- $a=5;
以后,$b 的值变为了 5
这里是为了让大家理解函数的引用返回才使用静态变量的, 其实函数的引用返回多用在对象中
对象的调用
- [php] view plain copy print?
- <?
- class a{
- var $abc="ABC";
- }
- $b=new a;
- $c=$b;
- echo $b->abc;// 这里输出 ABC
- echo $c->abc;// 这里输出 ABC
- $b->abc="DEF";
- echo $c->abc;// 这里输出 DEF
- ?>
- <?
- class a{
- var $abc="ABC";
- }
- $b=new a;
- $c=$b;
- echo $b->abc;// 这里输出 ABC
- echo $c->abc;// 这里输出 ABC
- $b->abc="DEF";
- echo $c->abc;// 这里输出 DEF
- ?>
在 PHP 中, 对象的复制是通过引用来实现的
上列中 $b=new a; $c=$b; 其实等效于 $b=new a; $c=&$b;
PHP 中默认就是通过引用来调用对象, 但有时你可能想建立一个对象的副本, 并希望原来的对象的改变不影响到副本
为了这样的目的, PHP 定义了一个特殊的方法, 称为__clone.
引用的作用
如果程序比较大, 引用同一个对象的变量比较多, 并且希望用完该对象后手工清除它时使用 "&" 方式, 然后用 $var=null 的方式清除
另外, php 中对于大数组的传递, 建议用 "&" 方式, 可以节省内存空间使用
取消引用
当你 unset 一个引用, 只是断开了变量名和变量内容之间的绑定这并不意味着变量内容被销毁了例如:
- <?php
- $a = 1;
- $b =& $a;
- unset ($a);
- ?>
不会 unset $b, 只是 $a
global 引用
当用 global $var 声明一个变量时实际上建立了一个到全局变量的引用也就是说和这样做是相同的:
- <?php
- $var =& $GLOBALS["var"];
- ?>
这意味着, 例如, unset $var 不会 unset 全局变量
$this
在一个对象的方法中,$this 永远是调用它的对象的引用
php 中对于地址的指向 (类似指针) 功能不是由用户自己来实现的, 是由 Zend 核心实现的, php 中引用采用的是写时拷贝的原理,
就是除非发生写操作, 指向同一个地址的变量或者对象是不会被拷贝的
通俗的讲
1. 如果有下面的代码
$a="ABC";
$b=$a;
其实此时 $a 与 $b 都是指向同一内存地址而并不是 $a 与 $b 占用不同的内存
2. 如果在上面的代码基础上再加上如下代码
$a="EFG";
由于 $a 与 $b 所指向的内存的数据要重新写一次了, 此时 Zend 核心会自动判断自动为 $b 生产一个 $a 的数据拷贝, 重新申请一块内存进行存储
来源: https://juejin.im/entry/5aa247e16fb9a028c06a6c8b