參考我有這樣的代碼:PHP通行證通過的foreach
$a = array ('zero','one','two', 'three');
foreach ($a as &$v) {
}
foreach ($a as $v) {
echo $v.PHP_EOL;
}
有人可以解釋爲什麼輸出是: 零一個二兩。
來自zend認證學習指南。
參考我有這樣的代碼:PHP通行證通過的foreach
$a = array ('zero','one','two', 'three');
foreach ($a as &$v) {
}
foreach ($a as $v) {
echo $v.PHP_EOL;
}
有人可以解釋爲什麼輸出是: 零一個二兩。
來自zend認證學習指南。
因爲在第二個循環中,$v
仍然是對最後一個數組項的引用,所以它每次都被覆蓋。
你可以看到它這樣的:
$a = array ('zero','one','two', 'three');
foreach ($a as &$v) {
}
foreach ($a as $v) {
echo $v.'-'.$a[3].PHP_EOL;
}
正如你所看到的,最後一個數組項以當前循環值:「零」,「一」,「二」,然後它只是'兩個'...)
好吧,這意味着在最後一次迭代中最後一項還是保持兩次,或者再次分配兩次,爲什麼不是三次爲什麼在最後一次停止? :) – Centurion 2010-07-22 14:40:31
它不停止。最後一個數組項目分配有當前循環值。所以它被分配爲「零」,然後是「一個」,然後是「兩個」。在最後一次迭代中,由於之前的迭代,它被賦予了它自己的值,即'2'。所以它只是保持'兩'。 – Macmade 2010-07-22 14:46:11
提高輸出後,我能夠理解: '$ v獲得項[0](零)。 $ a [3]現在爲零 $ v獲得項目[1](一)。 $ a [3]現在是一個 $ v獲得項[2](兩個)。 $ a [3]現在是兩個 $ v獲得項目[3](兩個)。 $ a [3]現在是兩個' – Eduardo 2013-09-02 02:18:40
因爲如果你創建一個變量的引用,那個變量的所有名字(包括原始的)成爲引用。
如果是這種情況,那麼爲什麼如果在第二個循環中將$ v更改爲&$ v,它是否會改變結果,即它會迴應零個,一個,兩個,三個? – 2010-07-22 09:43:27
,因爲當您在第二個循環中使用&$ v時,您正在更改變量的引用。因此,問題被消除了。 – dejavu 2010-07-22 09:59:39
我不得不花幾個小時來弄清楚爲什麼每次迭代都會改變[3]。這是我到達的解釋。
PHP中有兩種類型的變量:正常變量和引用變量。如果我們將一個變量的引用賦值給另一個變量,該變量就成爲一個引用變量。
例如在
$a = array('zero', 'one', 'two', 'three');
如果我們做
$v = &$a[0]
第0個元素($a[0]
)成爲基準變量。 $v
指向該變量;因此,如果我們對$v
進行任何更改,它將反映在$a[0]
中,反之亦然。
如果我們現在做
$v = &$a[1]
$a[1]
將成爲一個參考變量,$a[0]
將成爲一個正常的變量(因爲沒有其他人指向$a[0]
將它轉換成一個正常的變量。PHP是足夠聰明到使其在沒有其他人朝它指向一個正常的變量)
這是在第一循環
foreach ($a as &$v) {
}
會發生什麼
最後一次迭代後$a[3]
是一個參考變量。
由於$v
指向$a[3]
到$v
導致變化的任何變化,以在第二回路$a[3]
,
foreach ($a as $v) {
echo $v.'-'.$a[3].PHP_EOL;
}
在每次迭代
如$v
變化,$a[3]
變化。 (因爲$v
仍然指向$a[3]
)。這就是爲什麼$a[3]
在每次迭代時都會發生變化的原因。
在最後一次迭代之前的迭代中,$v
被賦值爲'2'。由於$v
指向$a[3]
,$a[3]
現在得到值'2'。記住這一點。
在上一次迭代中,$v
(指向$a[3]
)現在的值爲'2',因爲$a[3]
在前一次迭代中被設置爲2。打印出two
。這解釋了在上次迭代中打印$ v時爲什麼會重複「two」。
感謝您的詳細解釋 – Vodaldrien 2013-05-22 12:45:53
我愛你的解釋,但這仍然是讓我不斷困惑的事情之一。我必須記住要安撫理智的人。 :-) – liamvictor 2015-07-14 10:37:49
很好解釋。謝謝! – phpnerd 2017-03-22 04:42:25
我發現這個例子也很棘手。爲什麼在最後一次迭代的第二次循環中沒有任何事情發生($ v保持'兩'),是$ v指向$ a [3](反之亦然),所以它不能賦值給自己,所以它保持以前分配的值:)
第一循環
$v = $a[0];
$v = $a[1];
$v = $a[2];
$v = $a[3];
是的!目前$v
= $a[3]
的位置。
第二環路
$a[3] = $v = $a[0], echo $v; // same as $a[3] and $a[0] == 'zero'
$a[3] = $v = $a[1], echo $v; // same as $a[3] and $a[1] == 'one'
$a[3] = $v = $a[2], echo $v; // same as $a[3] and $a[2] == 'two'
$a[3] = $v = $a[3], echo $v; // same as $a[3] and $a[3] == 'two'
因爲$a[3]
由前處理分配。
在閱讀本文之前,無法理解其他答案的含義。謝謝! – thanksd 2015-12-16 22:21:35
我也是:) tks !! – MarceloBoni 2017-01-21 02:48:58
此:
$a = array ('zero','one','two', 'three');
foreach ($a as &$v) {
}
foreach ($a as $v) {
echo $v.PHP_EOL;
}
相同
$a = array ('zero','one','two', 'three');
$v = &$a[3];
for ($i = 0; $i < 4; $i++) {
$v = $a[$i];
echo $v.PHP_EOL;
}
OR
$a = array ('zero','one','two', 'three');
for ($i = 0; $i < 4; $i++) {
$a[3] = $a[$i];
echo $a[3].PHP_EOL;
}
OR
$a = array ('zero','one','two', 'three');
$a[3] = $a[0];
echo $a[3].PHP_EOL;
$a[3] = $a[1];
echo $a[3].PHP_EOL;
$a[3] = $a[2];
echo $a[3].PHP_EOL;
$a[3] = $a[3];
echo $a[3].PHP_EOL;
我覺得這段代碼更清楚地顯示了程序。
<?php
$a = array ('zero','one','two', 'three');
foreach ($a as &$v) {
}
var_dump($a);
foreach ($a as $v) {
var_dump($a);
}
結果: (以最後兩個陣列上的注意)
array(4) {
[0]=>
string(4) "zero"
[1]=>
string(3) "one"
[2]=>
string(3) "two"
[3]=>
&string(5) "three"
}
array(4) {
[0]=>
string(4) "zero"
[1]=>
string(3) "one"
[2]=>
string(3) "two"
[3]=>
&string(4) "zero"
}
array(4) {
[0]=>
string(4) "zero"
[1]=>
string(3) "one"
[2]=>
string(3) "two"
[3]=>
&string(3) "one"
}
array(4) {
[0]=>
string(4) "zero"
[1]=>
string(3) "one"
[2]=>
string(3) "two"
[3]=>
&string(3) "two"
}
array(4) {
[0]=>
string(4) "zero"
[1]=>
string(3) "one"
[2]=>
string(3) "two"
[3]=>
&string(3) "two"
}
我來到這裏只是偶然和OP的問題了我的注意。不幸的是,我不明白上面的任何解釋。對我來說似乎每個人都知道,得到它,接受它,就是無法解釋。
幸運的是,從PHP文檔純句子上foreach使這完全清楚:
警告:
$value
的參考和最後一個數組元素甚至foreach循環後依然存在。建議通過unset()銷燬它。
'unset($ your_used_reference);'每次使用'foreach($ var as&$ your_used_reference)''! – Wrikken 2010-07-22 09:39:49
感謝您的意見,但我只是想了解第二個foreach如何工作的邏輯。 – Centurion 2010-07-22 12:07:19
爲什麼$ your_used_reference(或OP中的$ v)不會自動取消設置?它的範圍是foreach,不應該超越? – Hurix 2014-01-17 15:54:16