本文章來(lái)給大家介紹在php中我們常看到在在php變量前面加個(gè)&符號(hào),這個(gè)就是php中引用符號(hào)了,它可以用于各種變量、函數(shù)、對(duì)象了下面我來(lái)給各位詳細(xì)介紹php&符號(hào)用法.在 PHP 中引用意味著用不同的名字訪問(wèn)同一個(gè)變量?jī)?nèi)容.這并不像 C 的指針,它們是符號(hào)表別名.注意在 PHP 中,變量名和變量?jī)?nèi)容是不一樣的,因此同樣的內(nèi)容可以有不同的名字.PHP的引用是通過(guò)在變量名或者函數(shù)名前加&符號(hào)來(lái)實(shí)現(xiàn)的.下面解釋一下引用的幾種用法:
先來(lái)看官方法的說(shuō)明:
引用做什么
PHP 的引用允許用兩個(gè)變量來(lái)指向同一個(gè)內(nèi)容.意思是,當(dāng)這樣做時(shí):
- $a =& $b;
- ?>
這意味著 $a 和 $b 指向了同一個(gè)變量.
$a 和 $b 在這里是完全相同的,這并不是 $a 指向了 $b 或者相反,而是 $a 和 $b 指向了同一個(gè)地方.
Note:
Note:
如果對(duì)一個(gè)未定義的變量進(jìn)行引用賦值、引用參數(shù)傳遞或引用返回,則會(huì)自動(dòng)創(chuàng)建該變量.Example #1 對(duì)未定義的變量使用引用:
- function foo(&$var) { }
- foo($a); // $a is "created" and assigned to null
- $b = array();
- foo($b['b']);
- var_dump(array_key_exists('b', $b)); // bool(true)
- $c = new StdClass;
- foo($c->d);
- var_dump(property_exists($c, 'd')); // bool(true)
- ?>
同樣的語(yǔ)法可以用在函數(shù)中,它返回引用,以及用在 new 運(yùn)算符中(PHP 4.0.4 以及以后版本)
- $bar =& new fooclass();
- $foo =& find_var($bar);
- ?>
自 PHP 5 起,new 自動(dòng)返回引用,因此在此使用 =& 已經(jīng)過(guò)時(shí)了并且會(huì)產(chǎn)生 E_STRICT 級(jí)別的消息.
Note:
首先是變量的簡(jiǎn)單引用,允許你用兩個(gè)變量來(lái)指向同一個(gè)內(nèi)容,舉個(gè)簡(jiǎn)單的例子:
- $a = 5;
- $b = &$a;
- echo $b;
- $a++;
- echo $b;
- ?>
運(yùn)行這段代碼是讓$b來(lái)引用$a的內(nèi)容,然后改變$a的內(nèi)容,$b的內(nèi)容也會(huì)隨之變化.同樣的語(yǔ)法可以用在函數(shù)中,它返回引用,以及用在new 運(yùn)算符中:
- $bar =& new fooclass();
- $foo =& find_var ($bar);
- ?>
引用做的第二件事是用引用傳遞變量.這是通過(guò)在函數(shù)內(nèi)建立一個(gè)本地變量,并且該變量在呼叫范圍內(nèi)引用了同一個(gè)內(nèi)容來(lái)實(shí)現(xiàn)的.
說(shuō)的通俗點(diǎn)就是一個(gè)函數(shù)的參數(shù)是一個(gè)本地變量的引用.下面再舉例說(shuō)明一下:
- function foo(&$val1, $val2) {
- $val1 += 1;
- $val2 += 1;
- }
- $a=5;
- $b=10;
- foo($a,$b);
- echo $a;
- echo $b;
- ?>
運(yùn)行這段代碼是給函數(shù)傳遞兩個(gè)參數(shù),一個(gè)是引用$a的內(nèi)容,一個(gè)是$b的值,在執(zhí)行此函數(shù)后,發(fā)現(xiàn)$a的內(nèi)容改變了,而$b的內(nèi)容則沒(méi)有變化.PHP引用的第三個(gè)用法是引用返回,這個(gè)用法理解起來(lái)有點(diǎn)難度,引用返回用在當(dāng)你想用函數(shù)找到引用應(yīng)該被綁定在哪一個(gè)變量上面時(shí).當(dāng)返回引用時(shí),使用此語(yǔ)法:說(shuō)的簡(jiǎn)單點(diǎn),就還是引用函數(shù)的返回.但和參數(shù)傳遞不同,必須在函數(shù)定義和函數(shù)引用這兩個(gè)地方都用 & 符號(hào).下面舉個(gè)例子:
- function &find_var ($param)
- {
- /* ...code... */
- return $found_var;
- }
- $foo =& find_var ($bar);
- $foo->x = 2;
- ?>
這個(gè)例子給$foo 賦值是函數(shù)find_var的返回引用,所以在給$foo->x賦值時(shí)就是給find_var的返回引用賦值,而不是簡(jiǎn)單的賦值.PHP引用的最后一個(gè)用法是引用定位,主要有兩個(gè)應(yīng)用:一個(gè)是global 引用,當(dāng)用 global $var 聲明一個(gè)變量時(shí)實(shí)際上建立了一個(gè)到全局變量的引用.也就是和$var =& $GLOBALS["var"];是一樣的.另外一個(gè)是$this的用法,在一個(gè)對(duì)象的方法中,$this 永遠(yuǎn)是調(diào)用它的對(duì)象的引用.與指針的區(qū)別引用與指針很像,但是其并不是指針.
看如下的代碼:
- $a = 0;
- $b = &a;
- echo $a; //0
- unset($b);
- echo $a; //0
由于$b只是$a的別名,所以即使$b被釋放了,$a沒(méi)有任何影響,但是指針可不是這樣的.
看如下代碼:
- #include
- int main(int argc, char const *argv[]) {
- int a = 0;
- int* b = &a;
- printf("%in", a); //0
- free(b);
- printf("%in", a); //*** error for object 0x7fff6350da08:
- pointer being freed was not allocated
- }
由于b是指向a的指針,所以釋放了b的內(nèi)存之后,再訪問(wèn)a就會(huì)出現(xiàn)錯(cuò)誤,比較明顯的說(shuō)明了PHP引用與C指針的區(qū)別.
對(duì)象與引用
在PHP中使用對(duì)象的時(shí)候,大家總是被告知"對(duì)象是按照引用傳遞的",其實(shí)這是個(gè)誤區(qū).PHP的對(duì)象變量存儲(chǔ)的是此對(duì)象的一個(gè)標(biāo)示符,在傳遞對(duì)象的時(shí)候,其實(shí)傳遞的就是這個(gè)標(biāo)示符,而并不是引用.
看如下代碼:
- $a = new A;
- $b = $a;
- $b->testA = 2;
- /*
- * 此時(shí)$a,$b的關(guān)系:
- * +-----------+ +-----------------+
- * $a --> | object id | ---> | object(Class A) |
- * +-----------+ +-----------------+
- * ^
- * +-----------+ |
- * $b --> | object id | ---------+
- * +-----------+
- *
- *
- */
- $c = new B;
- $a = $c;
- $a->testB = "Changed Class B";
- /*
- * 此時(shí)$a,$b,$c的關(guān)系:
- * +-----------+ +-----------------+
- * $b --> | object id | ---> | object(Class A) |
- * +-----------+ +-----------------+
- *
- * +------------+
- * $a --> | object id2 | -------------+
- * +------------+ |
- * v
- * +------------+ +-----------------+
- * $c --> | object id2 | ---> | object(Class B) |
- * +------------+ +-----------------+
- */
- echo "object a: "; var_dump($a); //["testB"]=> string(15)
- "Changed Class B"
- echo "object b: "; var_dump($b); //["testA"] => int(2)
- echo "object c: "; var_dump($c); //["testB"]=> string(15)
- "Changed Class B"
如果對(duì)象是按照引用傳遞的,那么$a,$b, $c輸出的內(nèi)容應(yīng)該一樣,事實(shí)上結(jié)果并非如此.看下面通過(guò)引用傳遞對(duì)象的列子:
- $aa = new A;
- $bb = &$aa; // 引用
- $bb->testA = 2;
- /*
- * 此時(shí)$aa, $bb的關(guān)系:
- *
- * +-----------+ +-----------------+
- * $bb --> | object id | ---> | object(Class A) |
- * +-----------+ +-----------------+
- * ^
- * |
- * $aa ---------+
- *
- *
- */
- $cc = new B;
- $aa = $cc;
- $aa->testB = "Changed Class B";
- /*
- * 此時(shí)$aa, $bb, $cc的關(guān)系:
- *
- * +-----------+ +-----------------+
- * | object id | ---> | object(Class A) |
- * +-----------+ +-----------------+
- *
- * $bb ---->-----+
- * |
- * $aa ---->-----+
- * |
- * v
- * +------------+
- * | object id2 | --------------+
- * +------------+ |
- * v
- * +------------+ +-----------------+
- * $cc --> | object id2 | ---> | object(Class B) |
- * +------------+ +-----------------+
- */
- echo "object aa: "; var_dump($aa); //["testB"]=>string(15)
- "Changed Class B"
- echo "object bb: "; var_dump($bb); //["testB"]=>string(15)
- "Changed Class B"
- echo "object cc: "; var_dump($cc); //["testB"]=>string(15)
- "Changed Class B"
此時(shí)$aa,$bb,$cc三者內(nèi)容完全一樣,所以可以看出對(duì)象并不是按照引用傳遞,要盡快走出這個(gè)誤區(qū).
新聞熱點(diǎn)
疑難解答