PHP中變量引用與變量銷毀機(jī)制分析
本文實(shí)例分析了PHP中變量引用與變量銷毀機(jī)制。分享給大家供大家參考。具體分析如下:
變量是php中一個(gè)非常重要的類型了,我們的有數(shù)據(jù)都通過(guò)變量或常量來(lái)進(jìn)行操作,下文來(lái)看看變量引用與變量銷毀。
在php中,符號(hào)"&"表示引用。
1、看看不引用的情況是這樣子:
$b = $a;//這一步?jīng)]有在$a之前加符號(hào)&,像這樣子"$b= & $a"。沒(méi)有加&,實(shí)際上原理是會(huì)將變量$a復(fù)制拷貝一份,也就是內(nèi)存中重新申請(qǐng)一個(gè)地址存儲(chǔ)變量$b了
ps:在php中,使用"="直接賦值,其實(shí)就是拷貝一份右邊的變量給b,會(huì)生成一份內(nèi)存空間,結(jié)果可能是同樣的內(nèi)容在內(nèi)存中兩份。在有些關(guān)于php性能方面提到,這樣子會(huì)多占有內(nèi)存空間。不過(guò)我接觸中,大部分人沒(méi)怎么注意,其實(shí)一般應(yīng)用這樣子用產(chǎn)生的顯著差異并不明顯。不會(huì)看到什么效果,其實(shí)我本人也沒(méi)經(jīng)常使用&進(jìn)行引用,呵呵。只是我覺(jué)得,深入了解里面的實(shí)現(xiàn)原理,非常有必要。我喜歡關(guān)注原理性的東西。
2、使用符號(hào)&進(jìn)行引用
$b = &$a;
使用引用,php引擎不會(huì)拷貝一份變量,其實(shí)就是將指針指向了$a在內(nèi)存中的地址,$b中就是保存了這個(gè)指針。
所以使用引用的時(shí)候,把$b的值改變,$a也會(huì)跟著改變
比如:
$b = &$a;
$b = "test new value";//把b的值改掉,a的值也會(huì)跟著改變
echo $a;//輸出test new value,因?yàn)楦淖兞薭的值也會(huì)改變a的值。
經(jīng)常在定義函數(shù)的時(shí)候看到像這樣的情況:
{
//函數(shù)定義的內(nèi)容
$param++;
}
解釋:$param前面帶有引用,所以傳入進(jìn)來(lái)的參數(shù)并不會(huì)在內(nèi)存中拷貝一份,而是直接對(duì)原來(lái)的內(nèi)存空間進(jìn)行引用。所以:如果里對(duì)使用符號(hào)&傳入進(jìn)來(lái)的變量值進(jìn)行修改了,那么也會(huì)改變?cè)瓉?lái)的內(nèi)存空間中的值。
做個(gè)測(cè)驗(yàn)如下:
test($k);
echo $k;//結(jié)果$k的值被函數(shù)里面改變了,輸出9。
還會(huì)經(jīng)??吹竭@樣子調(diào)用函數(shù):
前面了解到php引擎的機(jī)制是:=會(huì)把右邊的內(nèi)容拷貝一份給予左邊的變量。所以使用&就是將函數(shù)的結(jié)果不會(huì)進(jìn)行拷貝一份,實(shí)際上我的理解是把指針給了左邊的變量。
什么是指針,以前學(xué)c語(yǔ)言中的概念。我的理解是就是:指針,指針,指向針(指南針,呵呵)。把指針看成是一個(gè)內(nèi)存的地址容易理解點(diǎn),計(jì)算機(jī)就知道去內(nèi)存什么位置找數(shù)據(jù)了吧。這是淺顯的理解,深入的我不會(huì),呵呵。
總結(jié):使用引用是為了減少內(nèi)存資源的占用。
php手冊(cè)中對(duì)引用的解釋如下:
在 PHP 中引用意味著用不同的名字訪問(wèn)同一個(gè)變量?jī)?nèi)容。這并不像 C 的指針,替代的是,引用是符號(hào)表別名。注意在 PHP 中,變量名和變量?jī)?nèi)容是不一樣的,因此同樣的內(nèi)容可以有不同的名字。最接近的比喻是 Unix 的文件名和文件本身——變量名是目錄條目,而變量?jī)?nèi)容則是文件本身。引用可以被看作是 Unix 文件系統(tǒng)中的 hardlink。
3、銷毀變量的時(shí)候。并不會(huì)改變?cè)瓉?lái)的值。
試驗(yàn):$b = & $a;
既然改變$b的值,$a的值也跟著改變,假如把$b銷毀掉(內(nèi)存中不占用空間了,不是null,也不是值為""),$a的值是不是也會(huì)跟著被刪掉呢?
其實(shí)國(guó)外有本php方面的書(shū)中專門提到了這個(gè)機(jī)制。2年前看的。不是很記得了。原則是就是刪除變量的時(shí)候,會(huì)自動(dòng)拷貝。
其實(shí)這樣子,就是為了避免把$b給刪掉,造成把$a也給刪掉的問(wèn)題。
$a = 'd';
$b = & $a;
$b = 8;//因?yàn)槭且昧耍园裝的值改掉,a的值也跟著改為8了。
var_dump($b,$a);
unset($b);//調(diào)用unset刪除b變量,a變量不會(huì)刪除
var_dump($b,$a);//輸出null和8
調(diào)用unset刪除$b變量的時(shí)候,php引擎從變量符號(hào)表中發(fā)現(xiàn):我要?jiǎng)h除的變量$b原來(lái)是引用了變量$a,這不好刪除啊,因?yàn)橐粍h除導(dǎo)致$a變量也沒(méi)了,所以就先把$a變量拷貝一份后在刪除$b變量。
關(guān)于php符號(hào)表:其實(shí)我的理解是,運(yùn)行中所有變量名稱都記錄在里面,php來(lái)維護(hù),具體的數(shù)據(jù)當(dāng)然是存儲(chǔ)在內(nèi)存中,php就是根據(jù)這個(gè)符號(hào)表去回收沒(méi)有用到的變量空間的,釋放內(nèi)存空間)。去看看php的垃圾回收機(jī)制(釋放不再使用的內(nèi)存空間),就是根據(jù)符號(hào)表進(jìn)行的。
例子
$long="big_long_variable_name";
$$long="PHP"; /* 用存放在變量$long里的字符串作為新變量的變量名,等同于$big_long_variable_name="PHP"; */
$short=& $big_long_variable_name; /* 取變量$big_long_variable_name的值賦給變量$short,此時(shí)$short的值為"PHP",等同于$short=& $$long; */
print "01 /$short is $short."; /* "/$"是轉(zhuǎn)義序列,表示輸出一個(gè)美元符號(hào)$,下同。本語(yǔ)句的作用是輸出:01 $short is PHP. */
print "02 Long is $big_long_variable_name."; /* 輸出:02 Long is PHP. */
?>
<br />
<br />
<?php
$big_long_variable_name.=" rocks!"; /* 重新對(duì)$big_long_variable_name賦值。重新賦值過(guò)程中,由于在$big_long_variable_name的后面添加了.(點(diǎn)號(hào)),因而變量$big_long_variable_name此時(shí)的值應(yīng)為原值("PHP")+新值(" rocks!"),即變量$big_long_variable_name當(dāng)前完整的值為"PHP rocks!"。下同。*/
print "03 /$short is $short"; /* 輸出:03 $short is PHP rocks! */
print "04 Long is $big_long_variable_name"; /* 輸出:04 Long is PHP rocks! */
?>
<br />
<br />
05 $short is PHP rocks!
06 Long is PHP rocks!
<br />
<br />
<?php
$short.="Programming $short"; /* 重新對(duì)變量$short賦值。由于在$short后面添加了.(點(diǎn)號(hào)),因此請(qǐng)參考上例分析$short的值。*/
print "07 /$short is $short"; /* 輸出:07 $short is PHP rocks!Programming PHP rocks! */
print "08 Long is $big_long_variable_name"; /* 由于變量$short被重新賦值為Programming PHP rocks!,因而變量$big_long_variable_name的值也與$short一同被改變?yōu)?PHP rocks!Programming PHP rocks!"。本語(yǔ)句輸出:08 Long is PHP rocks!Programming PHP rocks!注意,如果是對(duì)具有相同值的一個(gè)變量進(jìn)行銷毀unset( ),則另一個(gè)變量不適用于此種情況,即不會(huì)隨之被一同銷毀。*/
?>
<br />
<br />
09 $short is Programming PHP rocks!
10 Long is Programming PHP rocks!
<br />
<br />
<?php
$big_long_variable_name.="Web Programming $short"; /* 變量$big_long_variable_name被重新賦值,此時(shí)它完整的值應(yīng)為PHP rocks!Programming PHP rocks!Web Programming PHP rocks!Programming PHP rocks!。變量$short的值此時(shí)與變量$big_long_variable_name一致。請(qǐng)分別參考第5處、第10處注釋進(jìn)行分析。*/
print "11 /$short is $short"; /* 輸出:11 PHP rocks!Programming PHP rocks!Web Programming PHP rocks!Programming PHP rocks! */
print "12 Long is $big_long_variable_name";
?>
<br />
<br />
<?php
unset($big_long_variable_name); /* 用unset( )銷毀變量$big_long_variable_name,變量$short不會(huì)因此受到任何影響。*/
print "13 /$short is $short"; /* 雖然銷毀了變量$big_long_variable_name,但$short沒(méi)有受到影響,它的值仍是最近一次被賦予的PHP rocks!Programming PHP rocks!Web Programming PHP rocks!Programming PHP rocks! */
print "14 Long is $big_long_variable_name."; /* 變量$big_long_variable_name已被銷毀,故而無(wú)值。輸出:14 Long is. */
snow;
?>
<br />
<br />
<?php $short="No point TEST1"; /* 重新對(duì)變量$short賦值。由于這次沒(méi)有在$short后面添加.(點(diǎn)號(hào)),因此$short當(dāng)前的值為"No point TEST1"。*/
print "15 /$short is $short."; /* 輸出:15 $short is No point TEST1. */
$short="No point TEST2 $short"; /* 重新對(duì)變量$short賦值。沒(méi)在$short的后面添加.(點(diǎn)號(hào)),但引用了它自身最近一次的值"No point TEST1"。*/
print "16 /$short is $short."; /* 輸出:16 $short is No point TEST2 No point TEST1. */
希望本文所述對(duì)大家的php程序設(shè)計(jì)有所幫助。
- PHP中函數(shù)內(nèi)引用全局變量的方法
- 淺談PHP變量作用域以及地址引用問(wèn)題
- 淺談PHP中關(guān)于foreach使用引用變量的坑
- PHP變量的定義、可變變量、變量引用、銷毀方法
- 深入理解PHP變量的值類型和引用類型
- php引用地址改變變量值的問(wèn)題
- 一道關(guān)于php變量引用的面試題
- php 變量引用與變量銷毀機(jī)制詳細(xì)介紹
- php中引用&的用法分析【變量引用,函數(shù)引用,對(duì)象引用】
- 淺析PHP原理之變量分離/引用(Variables Separation)
- 詳解PHP變量傳值賦值和引用賦值變量銷毀
- php 多個(gè)變量指向同一個(gè)引用($b = &$a)用法分析
相關(guān)文章
PHP Session條件競(jìng)爭(zhēng)超詳細(xì)講解
這篇文章主要介紹了PHP Session條件競(jìng)爭(zhēng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-12-12基于php雙引號(hào)中訪問(wèn)數(shù)組元素報(bào)錯(cuò)的解決方法
下面小編就為大家分享一篇基于php雙引號(hào)中訪問(wèn)數(shù)組元素報(bào)錯(cuò)的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-02-02ThinkPHP使用心得分享-上傳類UploadFile的使用
ThinkPHP中的UploadFile類用于處理文件上傳,本文小總結(jié)了一下關(guān)于學(xué)習(xí)過(guò)程中對(duì)UploadFile類的使用方法。2014-05-05php驗(yàn)證郵箱和ip地址最簡(jiǎn)單方法匯總
這篇文章為大家分享了php驗(yàn)證郵箱和ip地址最簡(jiǎn)單的方法,,需要的朋友可以參考下2015-10-10利用php獲取服務(wù)器時(shí)間的實(shí)現(xiàn)代碼
本篇文章是對(duì)使用php獲取服務(wù)器時(shí)間的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06PHP設(shè)計(jì)模式之裝飾者模式代碼實(shí)例
這篇文章主要介紹了PHP設(shè)計(jì)模式之裝飾者模式代碼實(shí)例,裝飾者模式就是不修改原類代碼和繼承的情況下動(dòng)態(tài)擴(kuò)展類的功能,本文就給出了代碼實(shí)例,需要的朋友可以參考下2015-05-05PHP面向?qū)ο笕筇攸c(diǎn)學(xué)習(xí)(充分理解抽象、封裝、繼承、多態(tài))
PHP面向?qū)ο笕筇攸c(diǎn)學(xué)習(xí) 學(xué)習(xí)目標(biāo):充分理解抽象、封裝、繼承、多態(tài)2012-05-05php 無(wú)極分類(遞歸)實(shí)現(xiàn)代碼
php 無(wú)極分類(遞歸)實(shí)現(xiàn)代碼,需要的朋友可以參考下。2010-01-01PHP模擬登錄時(shí)跳過(guò)HTTPS驗(yàn)證的方法
在PHP中,要跳過(guò)HTTPS的驗(yàn)證,可以使用cURL庫(kù)的CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST選項(xiàng),這些選項(xiàng)允許你禁用對(duì)SSL證書(shū)的驗(yàn)證,本文通過(guò)代碼示例展示了如何在PHP中模擬登錄時(shí)跳過(guò)HTTPS驗(yàn)證2023-10-10