Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Language Reference : Control Structures : break

break

break ends execution of the current for, foreach, while, do-while or switch structure.

break accepts an optional numeric argument which tells it how many nested enclosing structures are to be broken out of.

<?php
$arr
= array('one', 'two', 'three', 'four', 'stop', 'five');
while (list(,
$val) = each($arr)) {
if (
$val == 'stop') {
break;
/* You could also write 'break 1;' here. */
}
echo
"$val<br />\n";
}

/* Using the optional argument. */

$i = 0;
while (++
$i) {
switch (
$i) {
case
5:
echo
"At 5<br />\n";
break
1; /* Exit only the switch. */
case 10:
echo
"At 10; quitting<br />\n";
break
2; /* Exit the switch and the while. */
default:
break;
}
}
?>

Related Examples ( Source code ) » control_structures.break



Code Examples / Notes » control_structures.break

traxer

vlad at vlad dot neosurge dot net wrote on 04-Jan-2003 04:21
> Just an insignificant side not: Like in C/C++, it's not
> necessary to break out of the default part of a switch
> statement in PHP.
It's not necessary to break out of any case of a switch  statement in PHP, but if you want only one case to be executed, you have do break out of it (even out of the default case).
Consider this:
<?php
$a = 'Apple';
switch ($a) {
default:
echo '$a is not an orange
';
case 'Orange':
echo '$a is an orange';
}
?>
This prints (in PHP 5.0.4 on MS-Windows):
$a is not an orange
$a is an orange
Note that the PHP documentation does not state the default part must be the last case statement.


develop

To php_manual at pfiff-media dot de:
This is only possible with PHP5, because <PHP5 doesn't have a proper exception infrastructure.


pinkgothic

To add to the responses given to "vlad at vlad dot neosurge dot net" - I'd like to note the lack of automatic breaking in 'default' can be a very good thing. Consider this useful snippet:
<?php
switch((string) $_REQUEST['mode']) {
 default:
    $_REQUEST['mode'] = "search";
    // fall through...
 case 'search' :
 case 'list' :
 case 'add' :
 case 'edit' :
    require(dirname(__FILE__)."/incs/".$_REQUEST['mode'].".php");
    break;
}
?>
I personally find that far easier to look at than, for example:
<?php
$valid_modes = array('search','list','add','edit');
if (in_array($_REQUEST['mode'],$valid_modes)) {
    require(dirname(__FILE__)."/incs/".$_REQUEST['mode'].".php");
} else {
    require(dirname(__FILE__)."/incs/search.php");
}
?>
...and it even has the added benefit that the switch() variant only has one require() statement, which makes for easier maintenance, e.g. if the directory changes, or what-have-you.
(Consider the above pseudocode, please, it's not tested - it's code illustrating a point only.)


abodeman

The use of "break n" to break out of n enclosing blocks is generally a pretty dangerous idea. Consider the following.
Let's say you have a text file that contains some lines of text, as most text files do. Let's also say that you are writing a little piece of PHP to parse each line and interpret it as a string of commands. You might first write some test code just to interpret the first character of each line, like this:
<?php
$num = 0;
$file = fopen("input.txt", "r");
while (!feof($file)) {
   $line = fgets($file, 80);
   switch ($line{0}) {
       // Arbitrary code here--the details aren't important
       case 'i': // increment
           echo ++$num." ";
           break;
       case 'f': // find factors
           for ($factor = 1; $factor <= $num; ++$factor) {
               if ($num % $factor == 0) {
                   echo "[".$factor."] ";
                   // stop processing file if 7 is a factor
                   if ($factor == 7)
                       break 3; // break out of while loop
               }
           }
   }
}
fclose($file);
?>
So, now that you have this magnificent piece of test code written and working, you would want to make it parse all the characters in each line. All you have to do is put a loop around the switch statement, like so:
<?php
$num = 0;
$file = fopen("input.txt", "r");
while (!feof($file)) {
   $line = fgets($file, 80);
   for ($i = 0; $i < strlen($line); ++$i) {
       switch ($line{$i}) {
           // Arbitrary code here--the details aren't important
           case 'i': // increment
               echo ++$num." ";
               break;
           case 'f': // find factors
               for ($factor = 1; $factor <= $num; ++$factor) {
                   if ($num % $factor == 0) {
                       echo "[".$factor."] ";
                       // stop processing file if 7 is a factor
                       if ($factor == 7)
                           break 3; // break out of while loop
                   }
               }
       }
   }
}
fclose($file);
?>
(Of course, you changed "$line{0}" to "$line{$i}", since you need to loop over all the characters in the line.)
So now you go and try it out, and it doesn't work. After a bunch of testing, you discover that when 7 is a factor, the code stops processing the current line, but continues to process the remaining lines in the file. What happened?
The problem is the "break 3;". Since we added another loop, this doesn't break out of the same loop it did before. In a small program like this, it's not too difficult to find this problem and fix it, but imagine what it would be like if you have thousands of lines of PHP with a numbered break statement hidden in the mess somewhere. Not only do you have to find it, you also have to figure out how many layers you want to break out of.
Unfortunately, PHP doesn't really offer any alternative to numbered break statements. Without line labels, there's no way to refer to a specific loop. There is also no "goto" statement in PHP. You could kludge your way around things with something like
<?php
do {
   // some code
   if ($condition)
       break;
   // some more code
} while (FALSE);
?>
or
<?php
switch ($dummy) {
   default:
       // some code
       if ($condition)
           break;
       // some more code
}
?>
but these sorts of tricks quickly add an enormous amount of clutter to your code.
Thus, the moral of the story is simply to be very careful when using numbered break statements. The numbered break statement is one of the few language features that can break silently when other code is changed.


vinyanov

Note that the break argument accepts any expression, including a function result. So you may want to dynamically choose the loop level to break from:
<?php
// the print() function returns 1
function icarus()
{
while(print('sea level, '))
while(print('through the clouds, '))
while(print('close the Sun - '))
break rand(print('FEATHERS LOSS! - '), 3);

print('no feathers remaining.');
}
icarus();
?>


jonny arnold

Note that break also works with the foreach loop.

vlad

Just an insignificant side not: Like in C/C++, it's not necessary to break out of the default part of a switch statement in PHP.

php_manual

instead of using the while (1) loop with break like suggested in an earlier note, I would rather recommend throwing an exception, e.g.:
<?php
try {
  $query = "SELECT myAttr FROM myTable";
 $db = DB::connect($dbUrl);
  if (DB::isError($db)) {
   throw new Exception("Connection failed");
 }
 /* ... */
} catch (Exception $e) {
 echo "Error: ".$e->getMessage()."</br>";
}
?>


18-jan-2007 02:12

If you wonder how to end execution of a function (as I did), it's that simple: return
function foo($a) {
if(!$a) return;
echo 'true';
// some other code
}
foo(true) will echo 'true', foo(false) won't echo anything (as return ends execution of the function. Of course, therefore there is no need for 'else' before 'echo').


2et

If you need to execute a sequence of operations, where each step can generate an error, which you want to interrupt the sequence and you don't want to have an incrementing if...then...else/elseif indenting like this:
<?php
// Level 0 indenting.
$query = "SELECT myAttr FROM myTable";
$db = DB::connect($dbUrl);
if (DB::isError($db)) {
   // Level 1 indenting.
   echo "Error: Connection failed.<br/>";
} else {
   $dbResult = $db->query($query);
   if (DB::isError($dbResult)) {
       // Level 2 indenting.
       echo "Error: Query failed.<br/>";
   } else {
       // ...
   }
}
?>
First, elseif can be used to prevent indent level increase by replacing:
<?php
--
} else {
   $dbResult = $db->query($query);
   if (DB::isError($dbResult)) {
       // Level 2 indenting.
--
by
--
} elseif (DB::isError($dbResult = $db->query($query))) {
   // Level 1 indenting SUCCESS!
--
?>
However, it's not possible every time, because you can't reasonably put everything between the else and the if keywords in the if condition like above. Therefore, I suggest the following little trick using while and break:
<?php
while(1) {
// Level 1 indenting.
   $query = "SELECT myAttr FROM myTable";
   $db = DB::connect($dbUrl);
   if (DB::isError($db)) {
       // Level 2 indenting.
       echo "Error: Connection failed.<br/>";
       // Exit sequence.
       break;
   }
   // Back to level 1.
   $dbResult = $db->query($query);
   if (DB::isError($dbResult)) {
       // Level 2 indenting.
       echo "Error: Query failed.<br/>";
       // Exit sequence.
       break;
   }
   // Back to level 1.
   // ...
   // Quit while.
   break;
}
?>
Using do { ... } while(0) is even better, because the last break keyword can be removed.
Note: If you intend to use other statements using break (while, switch, for, foreach...) in the while(1) { ... } statement (or do while...), you can still exit using break's argument:
<?php
while (1) {
   while(cond) {
       if (error) {
           break 2;
       }
   }
}
?>


jody

If you are careful about repeating code when using multiple cases that pretty much do the same thing, you can use multiple cases for one block of code / one break. Below is an example.
<?php
switch($var)
 {
     case 'foo':
     case 'bar':
          //Processing code
     break;
 }
?>


ilene jones

For Perl or C programmers...
break is equivelant to last
while(false ! == ($site = $d->read()) ) {
 if ($site === 'this') {
    break;  // in perl this could be last;
 }
}


gautam

<?php
/*
break :break command exits the innermost loop construct which contains it.
break ends execution of the current for, foreach, while, do-while or switch structure.
break accepts an optional numeric argument which tells it how many nested enclosing structures are to be broken out of.
You can view various output by changing comparision operator(<,==,>) or value of $limit
*/
$to_square_root=65536;
$i=1;
$limit=4;
while (true) {
$square_root=sqrt($to_square_root);
echo "Square Root of $to_square_root is $square_root.
";
$to_square_root=$square_root;
$i=$i+1;
if ($i>$limit) // if ($i<$limit) is used, loop breaks on very first execution
break;
}
$loop=$i-1;
echo "This loop is executes for $loop times.";
/* Above codes produces following output in browser
Square Root of 65536 is 256
Square Root of 256 is 16
Square Root of 16 is 4
Square Root of 4 is 2
This loop is executes for 4 times
*/
?>


clean_code

"Just an insignificant side not: Like in C/C++, it's not necessary to break out of the default part of a switch statement in PHP."
--Yes it is, it's just that traditionally default: is the last entry of a switch and so nothing happens after.
-If it was, for whatever reason, not the last entry the script would bawk, there is no implicit break; associated with switch.


Change Language


Follow Navioo On Twitter
if
else
elseif
Alternative syntax for control structures
while
do-while
for
foreach
break
continue
switch
declare
return
require
include
require_once
include_once
eXTReMe Tracker