PHP的变量赋值

这个标题估计不少人会不屑一顾,变量赋值?excuse me?咱们学开发的第一课就会了好很差。可是,就是这样基础的东西,反而会让不少人蒙圈,好比,值和引用的关系。今天,咱们就来具体讲讲。php

首先,定义变量和赋值这个不用多说了吧git

$a = 1;
$b = '2';
$c = [4, 5, 6];
$d = new stdClass();

四个变量,分别定义了整型、字符串、数组的对象。这也是咱们每天要打交道的四种类型。github

而后,变量给变量赋值。数组

$a1 = $a;
$b1 = $b;
$c1 = $c;
$d1 = $d;

请注意,前三个的赋值都是正常的赋值,也就是对具体内容的拷贝。当咱们修改$a1的时候$a不会有变化。$a1是新开的内存空间保存了咱们的值。也就是说,他们的值是同样的,但内存地址不同。是两个没啥关系的长得很像的人而已。微信

可是$d1和$d就不是了,这两货不只值是同样的,内存地址也是同样的。这种状况就是咱们所说的引用赋值。当$d1发生变化时,$d2也会产生变化。框架

能够这么说:引用赋值就是为原变量创建了一个Windows下的快捷方式或者Linux中的软连接。oop

用具体的例子来讲明,首先是普通值的赋值:学习

// 普通赋值
$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产生影响。测试

那么对象形式的引用赋值呢?this

// 对象都是引用赋值
class A {
    public $name = '我是A';
}

$a = new A();
$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一个呗。

// 使用克隆解决引用传递问题
class Child{
    public $name = '我是A1的下级';
}
class A1 {
    public $name = '我是A';
    public $child;

    function __construct(){
        $this->child = new Child();
    }

    function __clone(){
        $this->name = $this->name;
        // new 或者用Child的克隆均可以
        // $this->child = new Child();
        $this->child = clone $this->child;
    }
}

$a1 = new A1();

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修改的内容没问题,b一、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

关注公众号:【硬核项目经理】获取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料

知乎、公众号、抖音、头条搜索【硬核项目经理】

B站ID:482780532

相关文章
相关标签/搜索