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

PHP的变量赋值

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

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

$a = 1;

$b = '2';

$c = [4, 5, 6];

$d = new stdClass();

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

然后,变量给变量赋值。

$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产生影响。

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

// 对象都是引用赋值

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

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

(0)

相关推荐

  • PHP变量赋值、代入给JavaScript中的变量

    复制代码 代码如下: $(document).ready(function(){ <?php $f="'name'"?>     var t=<?php echo $f?>;     alert(t)    }) 或 复制代码 代码如下: $(document).ready(function(){ <?php $f="name"?>     var t="<?php echo $f?>";    

  • PHP基础陷阱题(变量赋值)

    复制代码 代码如下: <?php $a=3; $b=6; if($a=5||$b=7){ $a++; $b++; } var_dump($a, $b); 陷阱一 把$a=5.$b=7看成了$a==5.$b==7 错误结果:3,6 陷阱二 运算符的优先级,认为$a=5赋值成功$b=7没执行 错误结果:6,7 正确理解 陷阱是运算符的优先,赋值运算符(=)的优先级是最低的,所以正确理解应该是 $a=(5||$b=7) 正确结果:true,7 升级一下 变形一 复制代码 代码如下: $a=3; $b=

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

    PHP的变量赋值 这个标题估计很多人会不屑一顾,变量赋值?excuse me?我们学开发的第一课就会了好不好.但是,就是这样基础的东西,反而会让很多人蒙圈,比如,值和引用的关系.今天,我们就来具体讲讲. 首先,定义变量和赋值这个不用多说了吧 $a = 1; $b = '2'; $c = [4, 5, 6]; $d = new stdClass(); 四个变量,分别定义了整型.字符串.数组的对象.这也是我们天天要打交道的四种类型. 然后,变量给变量赋值. $a1 = $a; $b1 = $b; $

  • 深入理解Python中变量赋值的问题

    前言 在Python中变量名规则与其他大多数高级语言一样,都是受C语言影响的,另外变量名是大小写敏感的. Python是动态类型语言,也就是说不需要预先声明变量类型,变量的类型和值在赋值那一刻被初始化,下面详细介绍了Python的变量赋值问题,一起来学习学习吧. 我们先看一下如下代码: c = {} def foo(): f = dict(zip(list("abcd"), [1, 2 ,3 ,4])) c.update(f) if __name__ == "__main__

  • 对变量赋值的理解--Pyton中让两个值互换的实现方法

    #Pyton中让两个值互换的实现方法 #方法一:可以理解为相当于是同时赋值 a = 5 b = 4 a,b = b,a print(a,b) #方法二:可以理解为拿箱子过程 c = 10 d = 20 e = c #定义第三个人e,将箱子 c 给 e 拿着 c = d #将箱子 d 给到 c d = e #将箱子 e 给到 d ,交换完成 print(c,d) 以上这篇对变量赋值的理解--Pyton中让两个值互换的实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我

  • python变量赋值方法(可变与不可变)

    python中不存在所谓的传值调用,一切传递的都是对象的引用,也可以认为是传址. 一.可变对象和不可变对象 Python在heap中分配的对象分成两类:可变对象和不可变对象.所谓可变对象是指,对象的内容可变,而不可变对象是指对象内容不可变. 不可变(immutable):int.字符串(string).float.(数值型number).元组(tuple) 可变(mutable):字典型(dictionary).列表型(list) 不可变类型特点: 看下面的例子(例1) i = 73 i +=

  • Python中的变量赋值

    目录 1 变量.对象.引用 2 对象的垃圾回收机制 3 变量所指向的对象不同会有何不同? 引言: Python中的变量在使用中很流畅,可以不关注类型,任意赋值,对于开发来说效率得到了提升,但若不了解其中的机理,往往也会犯一些小错,让开发进行的不那么流畅,本文就是从语言设计和底层原理的角度,带大家理解Python中的变量. 下面我们从一个简单例子开始: a = 3 当我们代码中写入a=3时到底发生了啥,从概念上来说,Python会执行三个不同的步骤来完成这个请求: 创建了一个对象来代表值3 若是a

  • JavaScript中的函数的两种定义方式和函数变量赋值

    复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <script type="text/javascript"> /*I总结: 1.函数名可以做变量使用,可以赋值,可以传值 2.函数名当参数,传递给另一个函数 */ //===========

  • jQuery ajax时间差导致的变量赋值问题分析

    本文实例分析了jQuery ajax时间差导致的变量赋值问题.分享给大家供大家参考,具体如下: ajax异步请求,在各种特效方面,做出了不少的贡献,有了它让用户体验更好.下面说一下曾今遇到过的一个问题,今天又遇到了,又花了我一点时间,小问题,但是特别容易忽视,并且不容易想到是什么原因产生的.废话不多说,举个例子大家就明白了. 一.准备测试文件test.php和test.html 1. test.php <?php echo "1"; ?> 2. test.html <

  • 深入理解Javascript作用域与变量提升

    下面的程序是什么结果? 复制代码 代码如下: var foo = 1;function bar() { if (!foo) {  var foo = 10; } alert(foo);}bar(); 结果是10: 那么下面这个呢? 复制代码 代码如下: var a = 1;function b() { a = 10; return; function a() {}}b();alert(a); 结果是1. 吓你一跳吧?发生了什么事情?这可能是陌生的,危险的,迷惑的,同样事实上也是非常有用和印象深刻

  • 分析 JavaScript 中令人困惑的变量赋值

    Javascript是一门弱类型的语言,声明变量不需要声明其类型,var x 就可以等于任何类型的值. 比如: var str = "string...."; var arr = ["this","is","array"]; var obj = {name:"caizhongqi",age:26,sex:"male"}; 这些都是正确的,这似乎非常简单方便,但是这种方便也会带来一些令人难

  • 深入理解PHP原理之异常机制

    PHP的异常机制的原理是什么? 在PHP每一个可独立执行的op array最后的ZEND_HANDLE_EXCEPTION是用来干什么呢? 让我们从一个问题说起, 上周的时候, blue5tar提了一个问题:"对于下面的代码, onError明明执行了, 但是onException却没有执行, 为什么?". 复制代码 代码如下: <?php function onError($errCode, $errMesg, $errFile, $errLine) { echo "

随机推荐