I am new to PHP and saw the code below online. It has continue 2 and break together in switch/case statement. What does it mean?
foreach ( $elements as &$element ) {
switch ($element['type']) {
case a :
if (condition1)
continue 2;
break;
case b :
if (condition2)
continue 2;
break;
}
// remaining code here, inside loop but outside switch statement
}
The continue 2 skips directly to the next iteration of the structure that is two levels back, which is the foreach. The break (equivalent to break 1) just ends the switch statement.
The behavior in the code you've shown is:
Loop through $elements. If an $element is type "a" and condition1 is met, or if it's type "b" and condition2 is met, skip to the next $element. Otherwise, perform some action before moving to the next $element.
From PHP.net:continue:
continue accepts an optional numeric argument which tells it how many
levels of enclosing loops it should skip to the end of. The default
value is 1, thus skipping to the end of the current loop.
From PHP.net:switch
PHP continues to execute the statements until the end of the switch
block, or the first time it sees a break statement.
If you have a switch inside a loop and wish to continue to the next
iteration of the outer loop, use continue 2.
continue accepts an optional numeric argument which tells it how many levels of enclosing loops it should skip to the end of. The default value is 1, thus skipping to the end of the current loop.
Source: http://php.net/manual/en/control-structures.continue.php
continue and break are similar in that the will stop something from happening.
in case of continue, it will stop anything after the braces but won't stop the loop. The switch statement just gets out of this statement and goes on to the next statement.
In case of break it will stop the entire loop from continuing, end the loop there.
Related
What is the different between
switch (variable) {
case 'value':
# code...
break;
case 'value':
# code...
break;
}
and this one
switch (variable) {
case 'value':
# code...
continue;
case 'value':
# code...
continue;
}
It's really different result or just same?
This is a special case for PHP because, as stated by the official documentation:
Note: In PHP the switch statement is considered a looping structure
for the purposes of continue. continue behaves like break (when no
arguments are passed). If a switch is inside a loop, continue 2 will
continue with the next iteration of the outer loop.
So in essence it means there is no actual difference between your two examples. However for clarity I think it would be best to use break as that is the standard in other languages. Note also that you could use continue 2 (or 3, 4...) to advance to the next iteration of a loop if the switch is inside a loop (or more).
In PHP the above two codes work in same way. Here the break and continue statement prevent control going to next case. That is the continue acts just like break here. Also switch is intended to be executed only once. It's not a loop. Hence continue is not relevant here.
Note:If there is loop enclosing this switch statement then the result will be different.
Here is a simple example code with both the switch cases mentioned above
<?php
$variable = 20;
echo "Normal<br/>";
switch ($variable) {
case '20':
echo "twenty";
break;
case '21':
echo "twenty one";
break;
}
echo "<br/><br/>With Continue<br/>";
switch ($variable) {
case '20':
echo "twenty";
continue;
case '21':
echo "twenty one";
continue;
}
?>
When I execute above code I got following output
Normal
twenty
With Continue
twenty
How?
Working of break statement
Break statement causes code execution to come out of the block and execute next statements because of which switch statement will execute only one case statement and exit out of switch block without executing other case blocks.
Working of Continue statement
Continue statement in case of loops will cause loop to stop execution of current iteration of loop and go for next iteration of the loop(if any exists) but in case of switch statement it is considered as a loop statement but no next iterations causing exit switch statement.
We can have a switch statement without break statements too like this
<?php
$variable = 20;
echo "Normal";
switch ($variable) {
case '19':
echo "<br/>Nineteen";
case '20':
echo "<br/>twenty";
case '21':
echo "<br/>twenty one";
case '23':
echo "<br/>twenty three";
}
?>
The output of above code will be
Normal
twenty
twenty one
twenty three
i.e. executing all the case statements after the case where first match is found.
In my simple code 'continue' skips the condition evaluation and jumps straight to beginning of loop body (the if line) causing infinite loop. I can see that's exactly what happens when debugging and resuming execution with breakpoint on loop condition (it doesn't break) or when using step over. Probably just me being tired but I'm clueless.
while ( ($line = _e(fgets($dump_file))) !== FALSE )
{
if ($line === '')
{
echo 'continue';
continue;
}
You should use the break keyword to stop a loop.
Continue will go to the beginning of the next loop iteration while skipping the rest of your loop.
More info :
http://php.net/manual/en/control-structures.break.php
http://php.net/manual/en/control-structures.continue.php
continue will always continue to the next iteration of the loop.
The loop is infinite because the value of $line never changes within the loop, so either the loop infinitely executes or never does at all depending on the initial value of $line.
break will break out of the loop
You're assigning the result of _e to $line in your while loop. I'm assuming you're getting _e from WordPress, which is documented here: http://codex.wordpress.org/Function_Reference/_e .
Return Values
(void)
This function does not return a value.
So, your loop basically says:
while (void !== False) {
continue;
}
Which, of course, continues forever.
Note that several answers have stated that the break statement should have been used. The code above is designed to abort the loop when the end of file (EOF) is hit, to which fgets returns False. Each time the loop is run, fgets reads the next line until it reaches the end of the file, at which point it returns False.
From php.net:
Returns a string of up to length - 1 bytes read from the file pointed to by handle. If there is no more data to read in the file pointer, then FALSE is returned.
The problem here isn't that a break statement is needed, because the while condition will be false when fgets returns False. The issue is that _e returns void which !== False and therefore the loop continues indefinitely.
Quick solution is to remove the _e in the while statement and apply it to the string later in your code block if necessary.
OK so here's what happened. Problem with the infinite loop was indeed due to my _e function not accounting for it's argument being FALSE value and always returning a string so the while loop condition would always evaluate to TRUE as suggested by Ryan Vincent and geis.
However that does not explain why my debugger would not break on the condition. Turns out that this problem is not related. The debugger it self is acting out and now refusing to break on all kinds of random breakpoints for no good reason.
Marking geis's answer as solution for all the effort.
I was looking through some code at work and found something I've not encountered before:
for (; ;)
{
// Some code here
break;
}
We call the function that contains this all the time, I only recently got in there to see how it works. Why does this work and is it documented somewhere?
It seems as though a while loop would have been more appropriate in this instance...
It's essentially the same as while(true). It doesn't have any initialisation, doesn't change anything between iterations, and in the absence of anything to make it false the condition is assumed to be true.
It's an infinite loop.
Normally you would have something like:
for ($i=0; $i<10; $i=$i+1)
But you can omit any of the parts.
These are all valid:
for ($i=0; ; $i=$i+1)
for (; $i<10; $i=$i+1)
for (; $i<10;)
However, if you omit the second part, there will be no condition for exiting the loop. This can be used if you do not know how many times you want to run the loop. You can use a break instruction to exit the loop in that case
for (;;)
{
// some code
if (some condition)
break;
}
Note that if you do not put a break the page will just get stuck and run indefinitely
The first blank statement is executed at the beginning.
The second blank expression (which determines whether you exit the loop or not) evaluates to TRUE implicitly:
http://php.net/manual/en/control-structures.for.php
The third blank statement executes after each iteration.
So any condition that kicks out of the loop will need to be in the loop itself.
I've seen this code, and I've no idea what it means.
while(true){
echo "Hello world";
}
I know what a while loop is, but what does while(true) mean? How many times will it executed. Is this not an infinite loop?
Although is an infinite loop you can exit it using break. It is useful when waiting for something to happen but you don't exactly know the number of iteration that will get you there.
Yes, this is an infinite loop.
The explicit version would be
while (true == true)
This is indeed (as stated already) an infinite loop and usually contains code which ends itself by using a 'break' / 'exit' statement.
Lots of daemons use this way of having a PHP process continue working until some external situation has changed. (i.e. killing it by removing a .pid file / sending a HUP etc etc)
Please referes to the PHP documentation currently at: http://www.w3schools.com/php/php_looping.asp
The while loop executes a block of code as long as the specified condition is true.
while (expression) {
statement(s)
}
The while statement evaluates expression, which must return a boolean value. If the expression evaluates to true, the
while statement executes the statement(s) in the while block. The
while statement continues testing the expression and executing its
block until the expression evaluates to false.
As a consequence, the code:
while (true) {
statement(s)
}
will execute the statements indefinitely because "true" is a boolean expression that, as you can expect, is always true.
As already mentioned by #elzo-valugi, this loop can be interrupted using a break (or exit):
while (true) {
statement(s)
if (condition) {
break;
}
}
It is indeed an infinite loop.
my switch statement has about ten outcome, but some of them need 1/2 loops to check, so i can't write them within case(condition), so i've tried using more than one default case, is this possible?
<?php
switch(true) {
case 1:
break;
case 2:
break;
default:
echo "this text is never printed ??";
while(true) {
while(true) { // case 3
break 3;
}
break;
}
while(true) {
// case 4
break 2;
}
case 5:
break;
default:
while(true) {
// case 6
break 2;
}
case 7:
break;
}
?>
is this sort of thing possible, as my first default doesn't seem to be executing at all?!
thanks
You cannot have more than one default in a switch statement. Also, default should be at the end of of the switch after all the case statements.
What might be happening when your code is run through the PHP engine is that the parser is reading the switch statements into a hash map type data structure and each time the parser finds a default label, it's overwriting the existing entry in the hash map. So only last default label ends up in the data structure that gets used in execution.
No this isn't possible, you can't have more than one default case in a switch statement, you'll need to put additional logic into the single final case statement.
when the default case is reached it captures all conditions so later cases are not evaluated.
To answer your question - no, it is only possible to have one default and that at the end. I'm not sure whether you can place other cases after the default, but what I'm sure of is that they would never be reached...
EDIT:
Also, I don't see what you're trying to do there. What's the point? Could you explain a bit? We might be able to help you accomplish what you want to do
You can have only one default in a switch. Remember that Zend is not the only thing that parses PHP, you may confuse other parsers by not putting the default case as the very last part of the switch.