首先,定义变量和赋值这个不用多说了吧
$a=1;$b='2';$c=[4,5,6];$d=newstdClass();
四个变量,分别定义了整型、字符串、数组的工具。这也是我们每天要打交道的四种类型。
然后,变量给变量赋值。
$a1=$a;$b1=$b;$c1=$c;$d1=$d;
请把稳,前三个的赋值都是正常的赋值,也便是对详细内容的拷贝。当我们修正$a1的时候$a不会有变革。$a1是新开的内存空间保存了我们的值。也便是说,他们的值是一样的,但内存地址不一样。是两个没啥关系的长得很像的人而已。
但是$d1和$d就不是了,这两货不仅值是一样的,内存地址也是一样的。这种情形便是我们所说的引用赋值。当$d1发生变革时,$d2也会产生变革。
可以这么说:引用赋值便是为原变量建立了一个Windows下的快捷办法或者Linux中的软链接。
用具体的例子来解释,首先是普通值的赋值:
//普通赋值$v='1';$c=$v;$c='2';echo$v,PHP_EOL;//'1'//数组也是普通赋值$arr1=[1,2,3];$arr2=$arr1;$arr2[1]=5;print_r($arr1);//[1,2,3]
$c不会对$v的值产生影响。$arr2修正了下标1,也便是第二个数字为5,当然也不会对$arr1产生影响。
那么工具形式的引用赋值呢?
//工具都是引用赋值classA{public$name='我是A';}$a=newA();$b=$a;echo$a->name,PHP_EOL;//'我是A'echo$b->name,PHP_EOL;//'我是A'$b->name='我是B';echo$a->name,PHP_EOL;//'我是B'
果真不出所料,\$b修正了name属性的内容后,$a里面的name也变成了$b所修正的内容。
在这种情形下,如果工具想要不是引用通报的,一是利用__clone(),也便是原型模式来进行自己的拷贝。二是从表面重新new一个呗。
//利用克隆办理引用通报问题classChild{public$name='我是A1的下级';}classA1{public$name='我是A';public$child;function__construct(){$this->child=newChild();}function__clone(){$this->name=$this->name;//new或者用Child的克隆都可以//$this->child=newChild();$this->child=clone$this->child;}}$a1=newA1();echo$a1->name,PHP_EOL;//输出a1原始的内容echo$a1->child->name,PHP_EOL;$b1=$a1;echo$b1->name,PHP_EOL;//b1现在也是a1的内容echo$b1->child->name,PHP_EOL;$b1->name='我是B1';//b1修正内容$b1->child->name='我是B1的下级';echo$a1->name,PHP_EOL;//a1变成b1的内容了echo$a1->child->name,PHP_EOL;//利用__clone$b2=clone$b1;//b2克隆b1$b2->name='我是B2';//b2修正内容$b2->child->name='我是B2的下级';echo$b1->name,PHP_EOL;//b1不会变成b2修正的内容echo$b1->child->name,PHP_EOL;echo$b2->name,PHP_EOL;//b2修正的内容没问题,b1、b2不是一个货了echo$b2->child->name,PHP_EOL;
工具的引用这一块确实会随意马虎让人蒙圈。特殊是更加繁芜的工具,内部的属性还有各种引用其他工具的时候。这种情形下一定要仔细确认引用赋值会不会带来问题,如果有问题,就利用新工具或者克隆技能进行引用问题的处理。
末了,轻松一下,引用变量的赋值就和我们给方法传引用参数一样的,利用一个&符号就可以啦!
//引用赋值$b=&$v;$b='3';echo$v,PHP_EOL;
本日我们更深入的学习和理解了一下PHP中的赋值问题,特殊是普通赋值和引用赋值的问题。下回看代码和框架的时候可以把稳把稳别人是怎么灵巧利用这两种赋值的哈,自己也能试试能不能利用这两种办法改造下自己曾经写过的BUG哦!
测试代码: https://github.com/zhangyue0503/dev-blog/blob/master/php/201910/source/PHP%E7%9A%84%E5%8F%98%E9%87%8F%E8%B5%8B%E5%80%BC.php
参考文档: https://www.php.net/manual/zh/language.variables.basics.php https://www.php.net/manual/zh/language.oop5.cloning.php