這個標題估計很多人會不屑一顧,變數賦值?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
https://www.php.net/manual/zh/language.oop5.cloning.php
關注公眾號:【硬核專案經理】獲取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、專案管理學習資料
知乎、公眾號、抖音、頭條搜索【硬核專案經理】
B站ID:482780532
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/247946.html
標籤:PHP
