首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 迴圈結構深度解析:while、for、foreach 效能與適用場景

     編輯:PHP 綜合知識

迴圈是處理重複邏輯的核心工具。PHP 提供 while、do-while、for、foreach 四種結構,各有優缺點與適用場景。本文深入分析執行機制、效能差異、常見錯誤與現代最佳實踐。

一、四大迴圈對照表

迴圈判斷時機適用場景典型用法
while前測未知次數、條件型、資料流讀取while ($row = $stmt->fetch())
do-while後測至少執行一次、選單互動選單輸入驗證
for前測已知次數、計數、複雜初始/遞增for ($i=0; $i<$n; $i++)
foreach內部迭代器陣列/可迭代物件遍歷(首選)foreach ($arr as $k=>$v)

二、while 實戰範例

1. 讀取資料庫結果集(PDO)

$stmt = $pdo->query('SELECT id, name FROM users');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    echo $row['name'] . PHP_EOL;
}

2. 檔案逐行讀取(記憶體友善)

$fp = fopen('large.log', 'r');
while (($line = fgets($fp)) !== false) {
    if (strpos($line, 'ERROR') !== false) {
        error_log($line);
    }
}
fclose($fp);

3. 產生斑馬紋表格(原文範例重構)

<table>
<?php
$i = 0;
while ($i < 100) {
    if ($i % 10 === 0) {
        if ($i > 0) echo '</tr>';
        $bg = ($i / 10) % 2 === 0 ? '#fff' : '#ccc';
        echo '<tr style="background:' . $bg . '">';
    }
    echo '<td>' . $i . '</td>';
    $i++;
}
if ($i % 10 !== 0) echo '</tr>';
?>
</table>

三、for 進階用法

1. 多重控制變數

for ($i = 0, $j = count($arr); $i < $j; $i++) {
    // $j 預先計算長度,避免每次呼叫 count()
}

2. 字串操作(如反轉)

$str = 'PHP';
$rev = '';
for ($i = strlen($str) - 1; $i >= 0; $i--) {
    $rev .= $str[$i];
}
// $rev = 'PHP' (回文)

3. 避免 for 遍歷關聯陣列

// 錯誤:關聯陣列鍵非連續整數
$arr = ['a'=>1, 'b'=>2];
for ($i=0; $i

四、foreach 核心機制與陷阱

1. 值傳遞 vs 參考傳遞

$arr = [1, 2, 3];

foreach ($arr as $v) { $v *= 2; }
print_r($arr); // [1, 2, 3] 未改變

foreach ($arr as &$v) { $v *= 2; }
print_r($arr); // [2, 4, 6] 已修改
unset($v);     // 必須解除參考,否則 $v 仍指向最後一個元素

2. 迴圈中修改陣列結構(危險)

$arr = [1, 2, 3, 4];
foreach ($arr as $k => $v) {
    if ($v === 3) unset($arr[$k]); // 可能導致跳過元素或無限迴圈
}
// 建議:先收集要刪除的鍵,迴圈後再刪除
$toDelete = [];
foreach ($arr as $k => $v) { if ($v === 3) $toDelete[] = $k; }
foreach ($toDelete as $k) unset($arr[$k]);

3. 遍歷多維陣列輸出表格

$data = [
    ['id'=>1, 'name'=>'Alice', 'age'=>25],
    ['id'=>2, 'name'=>'Bob',   'age'=>30],
];

echo '<table><tr><th>ID</th><th>Name</th><th>Age</th></tr>';
foreach ($data as $row) {
    echo '<tr>';
    foreach ($row as $cell) { echo '<td>' . htmlspecialchars($cell) . '</td>'; }
    echo '</tr>';
}
echo '</table>';

五、效能基準測試(百萬次迭代)

迴圈類型耗時記憶體備註
for ($i=0; $i<$n; $i++)基準極低純計數最快
while ($i++ < $n)+5~10%極低語意不同,非直接可比
foreach (range(1,$n) as $v)+30~50%高需建立陣列
foreach ($arr as $v)+10~20%低遍歷既有陣列首選

結論:計數用 for,遍歷陣列/物件用 foreach,條件流用 while。效能差異在百萬級才明顯,優先考慮可讀性與正確性。

六、each/list/reset 陣列指標操作(舊式)

PHP 7.2 棄用、8.0 移除 each(),新專案請勿使用。現代替代方案:

舊函數現代替代
each($arr)foreach ($arr as $k=>$v)
list($k,$v) = each($arr)foreach ($arr as $k=>$v)
current($arr)$arr[key($arr)] 或 reset($arr) 後 $arr[0]
reset/end/next/prevarray_keys()、array_values()、array_shift()、array_pop()

七、現代最佳實踐

  1. 優先 foreach:語意明確、支援參考修改、可迭代物件通用。
  2. 計數用 for:for ($i=0; $i<$len; $i++),$len 提前計算。
  3. 避免在迴圈中查詢資料庫/呼叫 API:改用批次查詢(WHERE id IN (...))或非同步佇列。
  4. 大量資料用 Generator:function gen() { for($i=0;$i<1e6;$i++) yield $i; } 逐個產出,記憶體常數級。
  5. 函數式替代:array_map、array_filter、array_reduce 表達資料轉換管線,減少副作用。

總結:理解四種迴圈的判斷時機、適用場景與 foreach 參考機制,配合 Generator 與函數式工具,即能應對從簡單計數到大規模資料串流的各種迴圈需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved