在 foreach 普及前,each() 配合 list() 是 PHP 遍歷數組的標準姿勢。本文深度剖析 each() 內部指針機制、list() 從右到左賦值邏輯、兩者結合的執行流程,並說明為何 PHP 7.2 棄用、8.0 移除 each(),給出現代最佳替代寫法。
array each ( array &$array )
[1=>value, 'value'=>value, 0=>key, 'key'=>key](數字鍵 0/1 和字符串鍵 key/value 並存)。false,需 reset($arr) 重置。list($a,$b) = [1,2] 先執行 $b=2 再 $a=1。$a 對應索引 0,$b 對應索引 1。Notice 並賦值 null。<?php
$arr = ['你','若','安','好','便','是','晴','天'];
// 寫法 1:for 循環 + list/each
for ( ; list($k, $v) = each($arr); ) {
echo "$k ~ $v\n";
}
// 寫法 2:while 循環(等價)
reset($arr);
while (list($k, $v) = each($arr)) {
echo "$k ~ $v";
}
// 輸出:
// 0 ~ 你
// 1 ~ 若
// 2 ~ 安
// 3 ~ 好
// 4 ~ 便
// 5 ~ 是
// 6 ~ 晴
// 7 ~ 天
?>
reset($arr) 指針指向索引 0。each($arr) 返回 [1=>'你', 'value'=>'你', 0=>0, 'key'=>0],指針移至索引 1。list($k, $v) = ...:$v = '你',$k = 0。each() 返回 false,循環結束。<?php
// 鍵名為 2,3,4,1 的非連續數組
list($a, $b, , $c) = [2=>10, 3=>20, 4=>30, 1=>40];
// 索引分布:0缺, 1=40, 2=10, 3=20, 4=30
// list 期望:$a=索引0, $b=索引1, $c=索引3
// 從右到左賦值:
// $c = 索引3 = 20
// $b = 索引1 = 40
// $a = 索引0 = Notice(缺失) -> null
// 結果:$a=null, $b=40, $c=20
?>
| 缺陷 | 影響 |
|---|---|
| 內部指針全局共享 | 巢狀循環、多處遍歷同一數組會相互干擾指針位置 |
| 不支援迭代器/對象 | 無法遍歷 Traversable、Generator、ArrayObject |
| 性能劣於 foreach | 每次調用需複製返回數組結構,foreach 直接操作內部 HashTable |
| 語義不清 | 副作用隱含在函數調用中,違反函數式純粹性 |