PHP中递减运算符(--$i)在不同代码场景下的行为差异原因
PHP表达式求值顺序导致的结果差异
场景一:分两行执行
代码:
$arr = array(1, 2, 3, 4, 5); $i = 5; while($i >= 1){ var_dump($i); var_dump($arr[--$i]); }
输出:
int(5) int(5) int(4) int(4) int(3) int(3) int(2) int(2) int(1) int(1)
场景二:合并为单行表达式
代码:
$arr = array(1, 2, 3, 4, 5); $i = 5; while($i >= 1){ var_dump($i == $arr[--$i]); }
输出:
bool(false) bool(false) bool(false) bool(false) bool(false)
差异原因分析
核心问题在于PHP对普通表达式的求值顺序没有强制规定(除了短路运算符、赋值运算符等少数特例),且同一个表达式内的变量修改会立即生效,导致不同写法下的求值逻辑完全不同:
场景一的执行逻辑
两行是独立的语句,执行顺序完全明确:
- 第一行
var_dump($i):直接输出当前$i的原始值(比如第一次循环时是5)。 - 第二行
var_dump($arr[--$i]):先执行前置自减--$i,$i的值立即减1(比如第一次循环后$i变成4),再取数组对应索引的值($arr[4]是5)。
所以两次输出的值看起来相等,本质是“原始$i值”和“减1后索引对应的数组值”巧合相等。
场景二的执行逻辑
$i == $arr[--$i]是同一个表达式,在你的PHP环境中,求值顺序是先计算右侧操作数:
- 先执行右侧的
--$i,$i的值立即减1(比如第一次循环时从5变成4),再取出$arr[4]的值5。 - 再计算左侧的
$i,此时$i已经是减后的值4。 - 比较4和5,结果为false。
后续循环以此类推:每次都是先把$i减1,再用减后的值和数组对应元素比较,自然全部不相等。
你忽略的细节
- PHP数组默认是0起始索引:$arr[0]=1、$arr[4]=5,你之前可能误以为索引和值一一对应,但实际是索引比值小1。
- 同一个表达式内的变量副作用(自增/自减)会立即生效,且普通表达式的求值顺序不固定,不能依赖“左到右”的直觉来写代码。
- 分语句执行时,变量的修改只会影响后续语句,而同一表达式内的修改会影响整个表达式的求值。
内容的提问来源于stack exchange,提问作者Sharanya Dutta
相关产品推荐
相关产品推荐

