$arr = [1,2,3]; foreach ($arr as &$value){} foreach ($arr as $value){}; echo $key; echo $value; echo "<pre>"; print_r($arr);exit;//1,2,2 原因如下: 无论foreach($arr as $key=>$value){}还是foreach ($arr as $key=>&$value){},最后都无法释放$key和$value变量指向的 内存地址。也就是说无论他们怎么遍历最后$key = count($arr),$value = $arr[count($arr)-1]; 1:引用遍历 由于是引用不是复制,所以最后$value变量和$arr[count($arr)-1]这个变量指向了同一个内存地址。两者一改都改。 所以foreach ($arr as &$value){}执行后$value 和 $arr[2]指向相同的内存地址。 再执行foreach ($arr as $value){}的时候 指针第一次指向1的内存地址,此时$value = 1;所以$arr[2] = 1;此时打印$arr = [1,2,1]; 第二次遍历指针指向2的内存地址,此时$value又被重新赋值为2,此时$arr[2] = 2; 此时打印$arr = [1,2,2]; 第三次遍历此时指针指向3的内存地址里面的值再第二次遍历的时候已经变成了2,此时$value = 2;此时打印$arr = [1,2,2]; 2:非引用遍历 非引用遍历是复制出$arr的值给$value;两者指向不同的内存地址,所以改变$value或者$arr对其他没有任何的影响。