奇怪的for循环语法

5

我已经学习PHP编程两年了。

我刚刚遇到了这个for循环:

    // Check the URI namespace for a context
    $wsDir = basename(dirname(__FILE__));
    $uriArr = explode("/", $_SERVER['REQUEST_URI']);

    for (
        $i = 0, $uriSize = sizeof($uriArr);
        $i < $uriSize && $uriArr[$i] != $wsDir && $i++;
    );

    $i++;
    self::$executionContext = isset($uriArr[$i]) && !empty($uriArr[$i]) && substr($uriArr[$i], 0, 1) != '?'
        ? strtoupper($uriArr[$i]) : 'SOAP';

我完全不知道这应该如何运作。

有人能向我解释一下吗?


5
如果你找到写那篇文章的人,我有几句话要对他说:P。 - Jonnix
看起来它正在找到URI中基本目录的结束位置。for循环不需要块,它将无条件地执行第一个表达式一次。然后,在第二个条件为真时执行第二个条件。第三个条件为空,意味着它什么也不执行。 - R. Chappell
PHP文档在示例4中展示了它可以在没有语句块的情况下使用。 - R. Chappell
@R.Chappell 如果你仔细看,你会发现for循环的条件是2而不是3。就我所知,这样做的唯一目的是初始化$i - Vasil Rashkov
1
@VasilShaddix 在 for 循环的第二个语句末尾有一个 ;,这表示有 3 个语句,只是第三个语句完全为空。 - R. Chappell
可读性就是扯淡。 - Napas
3个回答

7
这只是一个普通的三部分for循环,没有主语句和空的第三部分。
来自手册
for (expr1; expr2; expr3)
      statement

The first expression (expr1) is evaluated (executed) once unconditionally at the beginning of the loop.

In the beginning of each iteration, expr2 is evaluated. If it evaluates to TRUE, the loop continues and the nested statement(s) are executed. If it evaluates to FALSE, the execution of the loop ends.

At the end of each iteration, expr3 is evaluated (executed).

所以:
for (
    # initializes two variables
    $i = 0, $uriSize = sizeof($uriArr);

    # conditional, expr2
    $i < $uriSize && $uriArr[$i] != $wsDir && $i++;

    # no expr3
);

如果expr2的值为true,则循环继续。当然,没有语句或块需要执行,所以它只会跳到下一个迭代,这意味着expr2将在某个时刻反复执行,直到其值为false为止。
正如R. Chappell在评论中指出的那样,这可能是为了在字符串中查找位置。您可以使用类似的逻辑但更加“描述性”的方式重新编写此代码:
$uriSize = sizeof($uriArr)

for ($i = 0; $i < $uriSize; $i++) {
    if ($uriArr[$i] == $wsDir) break;
}

# now $i will be the index of the first $wsDir occurrence in the $uriArr array

这让我真正明白了。谢谢你,@sidyll。 - Vasil Rashkov
谢谢 @VasilShaddix,很高兴现在更清楚了。我刚刚用一种重写方法更新了答案。 - sidyll
1
谢谢提及 :) - R. Chappell

3

虽然有些晚了,但好像还没有人缓存这个:这个for循环等同于:

$i = 1;

为什么?因为在for循环的条件部分,有3个条件与AND绑定:

$i < $uriSize 
&&
$uriArr[$i] != $wsDir 
&&
$i++;

在第一次迭代中,$i++的值为0,相当于false,只有在之后才会递增。因此循环仅执行了一次,$i的值为1,这是一个bug。除非您的代码中有拼写错误...

你是个天才! - sidyll
我也来晚了。之后我看了一下代码,也发现了这个问题。谢谢你。这确实是正确的答案。 - Vasil Rashkov

2

这是使用没有第三个语句的for循环的另一个示例(不是答案)。它比原始问题更清晰。

for ($i=0; $i >= $i++ && $i <= 10; /* third statement */ );
echo $i;

这将基本上计数到10并输出,只有在PHP中使用增量运算符才能实现。
首先,我们将$i设置为零;
其次,我们检查并递增$i,以确保它大于或等于自己,同时小于或等于10。
第三,我们什么也不做...真没必要...
然而,普通人会写成相同的东西:
for ($i = 0; $i <= 10; $i++);
echo $i;

不过你需要想象一个更好的使用案例。是的,你可以只写$i = 10;,但这并不足以解释这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接