跳出if和foreach循环

350
我有一个foreach循环和一个if语句。如果找到匹配项,我最终需要跳出foreach循环。
foreach ($equipxml as $equip) {

    $current_device = $equip->xpath("name");
    if ($current_device[0] == $device) {

        // Found a match in the file.
        $nodeid = $equip->id;

        <break out of if and foreach here>
    }
}

针对 PHP 而言,我不能假设它们的行为相同。请勿将其与 JavaScript 混淆。 - au_stan
7
哎呀,我得停止过度使用jQuery。为什么会被踩?+1,这是个非常合理且表述清晰的问题。 - mrtsherman
13
我只是问了这个问题,因为(无论出于什么原因)我无法理解PHP中break语句的文档和示例。不过没关系,我来这里并不是为了获得徽章和积分,只是想要得到好的答案。 - au_stan
4个回答

756

if并不是一个循环结构,所以你不能“打破它”。

然而,你可以通过简单地调用break来跳出foreach。在你的例子中,这将产生期望的效果:

$device = "wanted";
foreach($equipxml as $equip) {
    $current_device = $equip->xpath("name");
    if ( $current_device[0] == $device ) {
        // found a match in the file            
        $nodeid = $equip->id;

        // will leave the foreach loop immediately and also the if statement
        break;
        some_function(); // never reached!
    }
    another_function();  // not executed after match/break
}

为了让其他遇到这个问题的人也能完整了解,只是为了补充一下..

break 可以带一个可选参数,用于指定 中断多少层 循环结构。例如:

foreach (['1','2','3'] as $a) {
    echo "$a ";
    foreach (['3','2','1'] as $b) {
        echo "$b ";
        if ($a == $b) { 
            break 2;  // this will break both foreach loops
        }
    }
    echo ". ";  // never reached!
}
echo "!";

输出结果:

1 3 2 1 !


2
非常有用,谢谢。如果提到参数会额外加分。if循环似乎像是一个hack,为什么不只是在另一个if中包装其余的语句呢?我知道你只是想帮忙,但请注意新手们。 - Dan Barron
3
如果你正在寻找如何打破一个包含 include 语句的循环,请使用 return 而不是 continue。 - Nick Constantine
如果是 switch 语句呢?switch 语句也使用 break。有人会简单地在 switch 中放两个 break,例如 { case "break": echo 'break the switch and the loop'; break;break; } 吗? - Jevon
@Jevon 不,你也可以简单地写成 switch($a) { case 'x': switch($b) { case 'x': break 2; }; break; } 内部的 break 2 将同时退出两个 switch 语句。 - Kaii

17
foreach($equipxml as $equip) {
    $current_device = $equip->xpath("name");
    if ( $current_device[0] == $device ) {
        // found a match in the file            
        $nodeid = $equip->id;
        break;
    }
}

只需使用break,就可以实现这一点。


那么,break是从foreach中跳出而不是if。我认为我的困惑来自于这个语句 if ($abort_if_block) break; 我最初设置的是 break 2,但失败了。谢谢。 - au_stan
2
小心break语句。如果你忘了在它后面加上分号,它可能会得到下一个表达式的结果并开始表现出意外行为(例如跳出比你想要的更多)。我知道每个人都建议不要使用GOTO,但我认为,在所有那些你真的无法找到比使用break更好的情况下,goto可能是一个更好的选择。当然,只限于向前跳(也不要跳太远),而且不要滥用!;-) - maraspin

3

在PHP中更安全的方法是通过嵌套递增计数器变量和if条件语句来退出foreachwhile循环。这比使用break;更加灵活,因为后者可能会在页面其他复杂部分引起混乱。

例如:

// Setup a counter
$ImageCounter = 0;

// Increment through repeater fields
while ( condition ):
  $ImageCounter++;

   // Only print the first while instance
   if ($ImageCounter == 1) {
    echo 'It worked just once';
   }

// Close while statement
endwhile;

2

对于那些来到这里但是正在寻找如何跳出包含 include 语句的循环的人,请使用 return 而不是 break 或 continue。

<?php

for ($i=0; $i < 100; $i++) { 
    if (i%2 == 0) {
        include(do_this_for_even.php);
    }
    else {
        include(do_this_for_odd.php);
    }
}

?>

如果你想要在 do_this_for_even.php 中使用 break 命令,你需要使用 return 命令。使用 break 或 continue 命令将会返回错误信息:Cannot break/continue 1 level。你可以在这里找到更多详细信息。


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