wyrwać się z czy i głosić

277

Mam pętlę foreach i instrukcję if. Jeśli zostanie znalezione dopasowanie, muszę ostatecznie wyrwać się z 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>
    }       
}
au_stan
źródło
dla php nie js. nie mogę założyć, że zachowują się tak samo.
au_stan
6
gee - muszę tak bardzo przestać używać jQuery. dlaczego otrzymało to głosowanie negatywne? +1, całkowicie rozsądne i dobrze postawione pytanie.
mrtsherman
11
zadałem tylko to pytanie, ponieważ (z jakiegokolwiek powodu) nie mogłem owinąć głowy doktorem php break i ich przykładami. wszystko dobrze. nie jestem tu po odznaki i punkty, po prostu dobre odpowiedzi.
au_stan

Odpowiedzi:

610

if nie jest strukturą pętlową, więc nie można się z niej „wyrwać”.

Możesz jednak wyjść z tego foreachpo prostu dzwoniąc break. W twoim przykładzie ma pożądany efekt:

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 and also the if statement
        break;
    }
    this_command_is_not_executed_after_a_match_is_found();
}

Tylko dla kompletności dla innych, którzy natkną się na to pytanie, szukając odpowiedzi ..

breakpobiera opcjonalny argument, który określa, ile struktur pętli powinno się złamać. Przykład:

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

Wynikowy wynik:

1 3 2 1!

Kaii
źródło
37
+1 - Świetne przykłady czegoś, z czym czasami doświadczają niedoświadczeni programiści.
Jim D
1
Przydatne, dziękuję. Dodatkowa karma za wymienienie argumentu. Jednak pętla if wydaje się być włamaniem. Dlaczego nie po prostu zawinąć pozostałe instrukcje w inne, jeśli? Wiem, że starałeś się być pomocny, ale zwróć uwagę początkujących.
Dan Barron,
3
Dla tych, którzy lądują tutaj, ale szukają sposobu na wyjście z pętli zawierającej instrukcję include, użyj return zamiast kontynuować.
Nick Constantine,
Co jeśli jest to instrukcja switch? Instrukcje switch używają również przerw. Czy ktoś po prostu umieściłby dwie przerwy w przełączniku, np. {Case "break": echo 'break the switch and the loop'; przerwa; przerwa; }?
Jevon,
@Jevon nie, po prostu napiszesz switch($a) { case 'x': switch($b) { case 'x': break 2; }; break; } również wewnętrzne break 2instrukcje obu instrukcji przełączania.
Kaii
13
foreach($equipxml as $equip) {
    $current_device = $equip->xpath("name");
    if ( $current_device[0] == $device ) {
        // found a match in the file            
        $nodeid = $equip->id;
        break;
    }
}

Po prostu użyj break. To wystarczy.

Przyzwoity Dabbler
źródło
więc przerwa odrywa się od foreach, a nie od tego. myślę, że moje zamieszanie wynikało z tego stwierdzenia, if ($abort_if_block) break;które pierwotnie ustaliłem break 2i nie udało się. dzięki
au_stan
2
Uważaj na konstrukcję break. Jeśli zapomnisz; po tym może otrzymać wynik następnego wyrażenia i zacząć zachowywać się nieoczekiwanie (IE wyskakuje z dużo więcej, niż byś chciał). Wiem, że wszyscy sugerują, aby nie używać GOTO, ale myślę, że we wszystkich przypadkach, w których nie da się zrobić nic lepszego niż skorzystanie z przerwy, lepo może być lepszą opcją. Oczywiście, tylko do skoków do przodu (również niezbyt daleko) i bez nadużyć! ;-)
maraspin
2

Bezpieczniejszym sposobem podejścia do zerwania pętli foreachlub whilew PHP jest zagnieżdżenie rosnącej zmiennej licznika i ifwarunkowe w oryginalnej pętli. Zapewnia to ściślejszą kontrolę, niż break;może to spowodować spustoszenie w innym miejscu na skomplikowanej stronie.

Przykład:

// 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;
serraosays
źródło
Składnia jest nieprawidłowa. Jeśli chcesz użyć endwhileinstrukcji, musisz napisać while (..): ...; endwhile;- zwróć uwagę na dwukropek tutaj while!
Kaii,
0

Dla tych, którzy lądują tutaj, ale szukają sposobu na wyjście z pętli zawierającej instrukcję include, użyj return zamiast break lub kontynuuj.

<?php

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

?>

Jeśli chcesz się złamać będąc w do_this_for_even.php, musisz użyć return. Użycie break lub kontynuuj zwróci ten błąd: Nie można przerwać / kontynuować 1 poziom. Znalazłem więcej szczegółów tutaj

Nick Constantine
źródło