这是我参与更文挑战的第4天,活动详情查看: 更文挑战
这几天看了不少关于引用Reference的东西,发现其实核心很简单,但是用起来不小心就会出错,就此总结一下,整理一些章法,给大家避坑提供一些指南。
我将引用分为3种引用场景:非数组变量引用,数组引用,以及函数引用。每一个场景都会按照赋值,传值,取消等等应用操作展开。
PHP引用的核心逻辑 &
引用的目的是什么:赋值,传值,返回值。
在PHP语境中,引用意味着用不同的变量名访问同一个变量内容。PHP变量名其实是个别名,一个变量值可以有多个别名,就好像一个人有大名,小名,笔名,说的都是他。这个和C语言中的指针是不一样的。
举个例子:
$a=1; $b=2; 想象这是计算机的内存:
| 指针 | 值 | PHP变量名 |
|---|---|---|
| 1 | 1 | $a |
| 2 | 2 | $b |
然后$c=&a,这时内存变为:
| 指针 | 值 | 变量名 |
|---|---|---|
| 1 | 1 | $a, $c |
| 2 | 2 | $b |
这时,如果我们改变$c的值,$c=3,这时的内存:
| 指针 | 值 | 变量名 |
|---|---|---|
| 1 | 3 | $a, $c |
| 2 | 2 | $b |
| $a也同步发生了改变 |
这时,我们再改变$a的引用,$a=&$b:
| 指针 | 值 | 变量名 | |
|---|---|---|---|
| 1 | 3 | $c | |
| 2 | 2 | $b, $a | |
| 那么再改变$c,就不会对$a有影响,因为$a的引用关系已经变了 |
这时,我们再引入一个$e, $e=&$a,多重引用下,内存的情况:
| 指针 | 值 | 变量名 | |
|---|---|---|---|
| 1 | 3 | $c | |
| 2 | 2 | $b, $a, $e | |
| 同样也是指向2 |
如果我们这时删除$b, unset($b),这时的内存:
| 指针 | 值 | 变量名 | |
|---|---|---|---|
| 1 | 3 | $c | |
| 2 | 2 | $a $e | |
| $a依然指向2,unset的只是变量名与变量的引用关系,并不会对其他变量和值有影响 |
好的,我们来总结一下,关于引用最核心的逻辑:
- PHP引用是给同一个变量起了另一个别名;
- 不存在多重引用,因为指向的都是同一个变量值;
- 引用的关系是多向的,不是单向的。改变一个变量的值,其他对该变量的引用也会同步发生改变;
- 删除一个引用变量,只是删除了这个变量名和变量值的关联,并不会影响其他引用,这个值也依然存在;
- 给一个变量新的引用赋值,则之前的引用关系被删除,对这个变量的操作将不再会影响到之前的引用值;
上面的5点核心逻辑都不难理解,但是在实际应用中,却有不少坑,比如下面:
$a = 1;
$b =& $a;
$c = $b;
$c = 7;
var_dump($a);
结果是int(1),为什么不是7呢?关键在第三步,$c=$b,这里的赋值只是将value进行传递,并没有建立引用$c和1的引用关系。
如果我们把第三步掉过来,变成$b=$c,那么$a的值就会变为7,因为$b的值是7.
需要注意的是,引用关联必须通过&进行传递,对于没有&的赋值,并不会传递引用关系,即便其中变量和其他变量有引用关系。
第一节讲完了,同学们,下课!
感谢阅读, 抛砖引玉, 如有不准确和错误之处请留言指正, 我会及时修正, 拜谢!
也欢迎热爱技术的小伙伴儿和我交流, 共同学习!
总结不易,请勿私自转载, 否则别怪老大爷不客气.
参考资料: www.php.net 官方文档