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

相關文章
相關標籤/搜索