Sau vòng lặp foreach đầu tiên, $item
vẫn là một tham chiếu đến một số giá trị cũng đang được sử dụng $arr[2]
. Vì vậy, mỗi foreach gọi trong vòng lặp thứ hai, không gọi bằng tham chiếu, thay thế giá trị đó, và do đó $arr[2]
, bằng giá trị mới.
Vì vậy, vòng 1, giá trị và $arr[2]
trở thành $arr[0]
, đó là 'foo'.
Vòng 2, giá trị và $arr[2]
trở thành $arr[1]
, đó là 'thanh'.
Vòng 3, giá trị và $arr[2]
trở thành $arr[2]
, đó là 'thanh' (vì vòng 2).
Giá trị 'baz' thực sự bị mất ở lần gọi đầu tiên của vòng lặp foreach thứ hai.
Gỡ lỗi đầu ra
Đối với mỗi lần lặp của vòng lặp, chúng ta sẽ lặp lại giá trị $item
cũng như in đệ quy mảng $arr
.
Khi vòng lặp đầu tiên được chạy qua, chúng ta sẽ thấy đầu ra này:
foo
Array ( [0] => foo [1] => bar [2] => baz )
bar
Array ( [0] => foo [1] => bar [2] => baz )
baz
Array ( [0] => foo [1] => bar [2] => baz )
Ở cuối vòng lặp, $item
vẫn chỉ đến cùng một nơi với $arr[2]
.
Khi vòng lặp thứ hai chạy qua, chúng ta sẽ thấy đầu ra này:
foo
Array ( [0] => foo [1] => bar [2] => foo )
bar
Array ( [0] => foo [1] => bar [2] => bar )
bar
Array ( [0] => foo [1] => bar [2] => bar )
Bạn sẽ nhận thấy mỗi mảng thời gian đưa một giá trị mới vào $item
, nó cũng được cập nhật $arr[3]
với cùng một giá trị đó, vì cả hai vẫn đang trỏ đến cùng một vị trí. Khi vòng lặp đến giá trị thứ ba của mảng, nó sẽ chứa giá trị bar
vì nó chỉ được đặt bởi lần lặp trước của vòng lặp đó.
Có phải là một lỗi?
Không. Đây là hành vi của một mục được tham chiếu và không phải là lỗi. Nó sẽ tương tự như chạy một cái gì đó như:
for ($i = 0; $i < count($arr); $i++) { $item = $arr[$i]; }
Một vòng lặp foreach không đặc biệt về bản chất trong đó nó có thể bỏ qua các mục được tham chiếu. Nó chỉ đơn giản là đặt biến đó thành giá trị mới mỗi lần như bạn sẽ ở ngoài vòng lặp.