深入淺出理解PHP原理之變量賦值
PHP的變量賦值
這個(gè)標(biāo)題估計(jì)很多人會(huì)不屑一顧,變量賦值?excuse me?我們學(xué)開發(fā)的第一課就會(huì)了好不好。但是,就是這樣基礎(chǔ)的東西,反而會(huì)讓很多人蒙圈,比如,值和引用的關(guān)系。今天,我們就來(lái)具體講講。
首先,定義變量和賦值這個(gè)不用多說(shuō)了吧
$a = 1; $b = '2'; $c = [4, 5, 6]; $d = new stdClass();
四個(gè)變量,分別定義了整型、字符串、數(shù)組的對(duì)象。這也是我們天天要打交道的四種類型。
然后,變量給變量賦值。
$a1 = $a; $b1 = $b; $c1 = $c; $d1 = $d;
請(qǐng)注意,前三個(gè)的賦值都是正常的賦值,也就是對(duì)具體內(nèi)容的拷貝。當(dāng)我們修改$a1的時(shí)候$a不會(huì)有變化。$a1是新開的內(nèi)存空間保存了我們的值。也就是說(shuō),他們的值是一樣的,但內(nèi)存地址不一樣。是兩個(gè)沒啥關(guān)系的長(zhǎng)得很像的人而已。
但是$d1和$d就不是了,這兩貨不僅值是一樣的,內(nèi)存地址也是一樣的。這種情況就是我們所說(shuō)的引用賦值。當(dāng)$d1發(fā)生變化時(shí),$d2也會(huì)產(chǎn)生變化。
可以這么說(shuō):引用賦值就是為原變量建立了一個(gè)Windows下的快捷方式或者Linux中的軟鏈接。
用具體的例子來(lái)說(shuō)明,首先是普通值的賦值:
// 普通賦值 $v = '1'; $c = $v; $c = '2'; echo $v, PHP_EOL; // '1' // 數(shù)組也是普通賦值 $arr1 = [1,2,3]; $arr2 = $arr1; $arr2[1] = 5; print_r($arr1); // [1, 2, 3]
$c不會(huì)對(duì)$v的值產(chǎn)生影響。$arr2修改了下標(biāo)1,也就是第二個(gè)數(shù)字為5,當(dāng)然也不會(huì)對(duì)$arr1產(chǎn)生影響。
那么對(duì)象形式的引用賦值呢?
// 對(duì)象都是引用賦值
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屬性的內(nèi)容后,$a里面的name也變成了$b所修改的內(nèi)容。
在這種情況下,如果對(duì)象想要不是引用傳遞的,一是使用__clone(),也就是原型模式來(lái)進(jìn)行自己的拷貝。二是從外面重新new一個(gè)唄。
// 使用克隆解決引用傳遞問(wèn)題
class Child{
public $name = '我是A1的下級(jí)';
}
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原始的內(nèi)容
echo $a1->child->name, PHP_EOL;
$b1 = $a1;
echo $b1->name, PHP_EOL; // b1現(xiàn)在也是a1的內(nèi)容
echo $b1->child->name, PHP_EOL;
$b1->name = '我是B1'; // b1修改內(nèi)容
$b1->child->name = '我是B1的下級(jí)';
echo $a1->name, PHP_EOL; // a1變成b1的內(nèi)容了
echo $a1->child->name, PHP_EOL;
// 使用__clone
$b2 = clone $b1; // b2克隆b1
$b2->name = '我是B2'; // b2修改內(nèi)容
$b2->child->name = '我是B2的下級(jí)';
echo $b1->name, PHP_EOL; // b1不會(huì)變成b2修改的內(nèi)容
echo $b1->child->name, PHP_EOL;
echo $b2->name, PHP_EOL; // b2修改的內(nèi)容沒問(wèn)題,b1、b2不是一個(gè)貨了
echo $b2->child->name, PHP_EOL;
對(duì)象的引用這一塊確實(shí)會(huì)容易讓人蒙圈。特別是更加復(fù)雜的對(duì)象,內(nèi)部的屬性還有各種引用其他對(duì)象的時(shí)候。這種情況下一定要仔細(xì)確認(rèn)引用賦值會(huì)不會(huì)帶來(lái)問(wèn)題,如果有問(wèn)題,就使用新對(duì)象或者克隆技術(shù)進(jìn)行引用問(wèn)題的處理。
最后,輕松一下,引用變量的賦值就和我們給方法傳引用參數(shù)一樣的,使用一個(gè)&符號(hào)就可以啦!
// 引用賦值 $b = &$v; $b = '3'; echo $v, PHP_EOL;
今天我們更深入的學(xué)習(xí)和了解了一下PHP中的賦值問(wèn)題,特別是普通賦值和引用賦值的問(wèn)題。下回看代碼和框架的時(shí)候可以注意注意別人是怎么靈活使用這兩種賦值的哈,自己也能試試能不能運(yùn)用這兩種方式改造下自己曾經(jīng)寫過(guò)的BUG哦!
測(cè)試代碼:
參考文檔:
到此這篇關(guān)于深入淺出理解PHP原理之變量賦值的文章就介紹到這了,更多相關(guān)PHP 變量賦值內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PHP單元測(cè)試?yán)?PHPUNIT深入用法(三)
在本系列文章的前兩篇中PHP單元測(cè)試?yán)鳎篜HPUNIT初探和PHP單元測(cè)試?yán)鳎篜HPUNIT深入用法(二)中,分別介紹了phpunit的基本用法和phpunit中的一些重要用法。2011-03-03
DedeCMS 核心類TypeLink.class.php摘要筆記
DedeCMS 核心類TypeLink.class.php摘要筆記,學(xué)習(xí)php就是借鑒與分析,讓自己的掌握的更多。2010-04-04
既簡(jiǎn)單又安全的PHP驗(yàn)證碼 附調(diào)用方法
這篇文章主要為大家分享了一段實(shí)用的PHP驗(yàn)證碼類,既簡(jiǎn)單又安全的PHP驗(yàn)證碼代碼,感興趣的小伙伴們可以參考一下2016-06-06
PHP正則的Unknown Modifier錯(cuò)誤解決方法
PHP正則時(shí)出現(xiàn)Unknown Modifier錯(cuò)誤解決方法2010-03-03

