深入浅出理解PHP原理之变量赋值

admin3年前PHP教程33

PHP的变量赋值

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

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

?

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






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

然后,变量给变量赋值。

?

1
2
3
4
5
6
7
$a1 = $a;
 
$b1 = $b;
 
$c1 = $c;
 
$d1 = $d;






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

但是$d1和$d就不是了,这两货不仅值是一样的,内存地址也是一样的。这种情况就是我们所说的引用赋值。当$d1发生变化时,$d2也会产生变化。

可以这么说:引用赋值就是为原变量建立了一个Windows下的快捷方式或者Linux中的软链接。

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

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 普通赋值
 
$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产生影响。

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

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 对象都是引用赋值
 
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一个呗。

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// 使用克隆解决引用传递问题
 
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修改的内容没问题,b1、b2不是一个货了
 
echo $b2->child->name, PHP_EOL;






对象的引用这一块确实会容易让人蒙圈。特别是更加复杂的对象,内部的属性还有各种引用其他对象的时候。这种情况下一定要仔细确认引用赋值会不会带来问题,如果有问题,就使用新对象或者克隆技术进行引用问题的处理。

最后,轻松一下,引用变量的赋值就和我们给方法传引用参数一样的,使用一个&符号就可以啦!

?

1
2
3
4
5
6
7
// 引用赋值
 
$b = &$v;
 
$b = '3';
 
echo $v, PHP_EOL;






今天我们更深入的学习和了解了一下PHP中的赋值问题,特别是普通赋值和引用赋值的问题。下回看代码和框架的时候可以注意注意别人是怎么灵活使用这两种赋值的哈,自己也能试试能不能运用这两种方式改造下自己曾经写过的BUG哦!

测试代码:

github/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

参考文档:

php/manual/zh/language.variables.basics.php

到此这篇关于深入浅出理解PHP原理之变量赋值的文章就介绍到这了,更多相关PHP 变量赋值内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:php/php-weizijiaocheng-482289

免责声明:本文内容来自用户上传并发布,站点仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。请核实广告和内容真实性,谨慎使用。

相关文章

如何选择合适的GPU服务器?成都GPU服务器选购注意事项?

如何选择合适的GPU服务器?选择GPU服务器时首先要考虑业务需求来选择适合的GPU型号。在HPC高性能计算中还需要根据精度来选择,比如有的高性能计算需要双精度,这时如果使用P40或者P4就不合适,只能...

济南高防服务器做游戏有哪些优势

使用济南高防服务器来做游戏有以下几个优势:高性能:游戏通常需要高性能的服务器来支持大量玩家同时在线,以及处理游戏数据的传输和计算。济南高防服务器通常具有高性能的CPU、内存和硬盘等硬件设备,可以提供稳...

国外站群服务器为何如此受欢迎的原因

国外站群服务器为何如此受欢迎的原因?1、应用国外站群服务器的网站更易于维护,假如应用的网站服务器沒有具备的那麼很多个IP得话,万一某一网站遭受恶意攻击,相同IP绑定了很多个网站,那麼就难以排查是哪个网...

高防服务器、高防ip和高防cdn三者有什么区别?国内电信100G高防服务器租用指南?

高防服务器主要是比普通服务器多了防护服务,一般都是在idc信息中心出口布署了专门的硬件防火墙设备以及流量清洗牵引设备等,用来防cc攻击和防ddos攻击。就目前的标准衡量,高防服务器是指能独立防护100...

详解PHP用mb_string处理windows中文字符

我们都知道windows中(当然是中文版),文件名和文件内容等编码都是gbk,而我们在开发过程中,IDE里的编码则是UTF-8,(这里不讨论为什么等等问题,只考虑怎么把编码转变成一样的)所以导致我写的...

韩国服务器租用哪个机房好用

韩国服务器租用哪个机房好用?选择一个好用的韩国服务器租用机房需要考虑多方面的因素,以下是一些可以参考的方法和指标:可靠性:选择一个可信赖的机房十分重要,因为如果机房出现故障或停电等问题,服务器将无法正...