【问题标题】:Why is this foreach loop iterating twice?为什么这个 foreach 循环迭代两次?
【发布时间】:2019-03-26 22:28:44
【问题描述】:

问题确实在标题中 - 我有这个 foreach 循环,它似乎在我的数组上迭代了两次。

ob_start();

$array = str_split(strtolower($_GET['text']));

foreach ($array as $char) {
    error_log($_GET['text'] . ', ' . sizeof($array) . ', ' . $char);
}

$result = ob_get_contents(); 

我发现上面的代码在像这样传递 URL 时会产生以下日志:index.php?text=Hi

[22-Oct-2018 20:05:37 Europe/London] Hi, 2, h
[22-Oct-2018 20:05:37 Europe/London] Hi, 2, i
[22-Oct-2018 20:05:37 Europe/London] Hi, 2, h
[22-Oct-2018 20:05:37 Europe/London] Hi, 2, i

调试显示数组只有 2 长,所以我真的不确定它可能是什么。谢谢!


经过多次调试,发现如下:

if (!isset($_GET['text'])) {
    header('HTTP/1.0 404 Not Found');
    die();
}

echo uniqid() . '</br>';

//ob_start();

$total = 0;
$array = str_split(strtolower($_GET['text']));

foreach ($array as $char) {
    echo $_GET['text'] . ', ' . sizeof($array) . ', ' . $char . '</br>';
}

//$result = ob_get_contents();

echo $result;

产生这个:

5bce311d3d6bd
Hi, 2, h
Hi, 2, i

但是取消注释两条注释掉的行,给了我这个:

5bce313b9f29d
Hi, 2, h
Hi, 2, i
Hi, 2, h
Hi, 2, i

【问题讨论】:

  • 但是每个字符的一个循环是两次迭代 - 这里的 OP 显示了四次迭代的输出。尽管我看不出所显示的代码会这样做的任何原因。除非脚本在同一秒内运行两次,否则写入显示的日志输出。
  • 不能仅从示例代码中重现。此外,不清楚代码/脚本是否被调用了两次(双重请求、浏览器预取等),或者输出在日志中结束了两次。
  • @mario 我稍微扩展了代码示例。添加似乎是原因,因为没有添加我也无法复制它。
  • 我看不出ob_XXX 函数会对error_log() 产生任何影响。
  • 尝试添加指标以确保脚本不会运行两次。例如,您可以使用uniqid() 在循环外设置一个变量并将其添加到您的日志中。

标签: php php-7.2


【解决方案1】:

我想我可能需要更多地了解ob_... 功能?

以下代码似乎是一致且可靠的:

if (!isset($_GET['text'])) {
    header('HTTP/1.0 404 Not Found');
    die();
}

echo uniqid() . '</br>';

ob_start();

$total = 0;
$array = str_split(strtolower($_GET['text']));

foreach ($array as $char) {
    echo $_GET['text'] . ', ' . sizeof($array) . ', ' . $char . '</br>';
}

ob_flush();

【讨论】: