| 運算符 | 名稱 | 操作順序 | 表達式值 |
| ++$i | 前置遞增 | 先加 1,後取值 | 新值 (加 1 後) |
| $i++ | 後置遞增 | 先取值,後加 1 | 舊值 (加 1 前) |
賦值表達式示例
前置遞增:$a = ++$i (假設 $i=2)
- $i = $i + 1 → $i = 3
- $a = $i → $a = 3
- 結果:$a=3, $i=3
等價於:$i = $i + 1; $a = $i;
後置遞增:$a = $i++ (假設 $i=2)
- $a = $i → $a = 2
- $i = $i + 1 → $i = 3
- 結果:$a=2, $i=3
等價於:$a = $i; $i = $i + 1;
單獨使用時
<?php
$i = 2;
++$i; // $i 變為 3
$i++; // $i 變為 4
// 單獨作語句時,兩者效果相同:$i = $i + 1
但**嵌入複合表達式時差異巨大**,如循環條件、函數參數、數組索引。
實戰陷阱案例
1. for 循環條件判斷
<?php
for ($i = 0; $i < 5; $i++) { /* ... */ } // 推薦:後置遞增,語義「用完再增」
for ($i = 0; $i < 5; ++$i) { /* ... */ } // 同樣正確,但語義稍異
// 反例:while 中混用導致邏輯錯誤
$i = 0;
while ($i++ < 5) { echo $i; } // 輸出 1 2 3 4 5 6 (多執行一次!)
$i = 0;
while (++$i < 5) { echo $i; } // 輸出 1 2 3 4 (正確 4 次)
2. 數組索引操作
<?php
$arr = [10, 20, 30];
$i = 0;
echo $arr[$i++]; // 10 (用舊索引 0)
echo $arr[++$i]; // 30 (索引已成 2,跳過 1)
3. 函數參數傳遞
<?php
function test($v) { echo $v; }
$i = 5;
test($i++); // 傳入 5,函數內輸出 5,外部 $i 變 6
test(++$i); // $i 先變 7,傳入 7,函數內輸出 7
最佳實踐建議
- 獨立語句統一用 ++$i:性能微優(無需保留舊值副本),語義明確「遞增」。
- 嵌入表達式時明確語義:需要「當前值」用
$i++,需要「新值」用 ++$i。
- 避免在複雜表達式中多次遞增同一變量:
foo($i++, $i++, ++$i) 行為在不同語言/版本中可能未定義,PHP 左到右求值但極難維護。
- 代碼審查關注點:循環條件、數組索引、函數調用參數中的遞增操作。
底層原理(ZEND VM)
PRE_INC 指令:直接對變量加 1,返回新值。
POST_INC 指令:複製當前值到臨時變量,原變量加 1,返回臨時值。
- 單獨語句編譯器優化:
$i++; 和 ++$i; 產生相同 opcode 序列(無需返回值)。
- 上一篇文章: PHP MSSQL 查詢結果獲取函數對比:mssql_fetch_row/array/assoc/object 返回結構差異詳解
- 下一篇文章: PHP 判斷目錄/文件讀寫權限:is_writable 陷阱、空目錄遞歸檢測、實戰封裝函數
Copyright ©
程式碼之家 All Rights Reserved