I just got bit by assuming the following:
foreach ($arr as $key => $value) {
switch($key) {
// ... some other cases
default:
continue;
// ^== assumption: move on to the next iteration of the foreach
// actual PHP: treat this continue just like a break
}
// ...
}
But in fact, according to the documentation for continue:
the switch statement is considered a looping structure for the purposes of continue.
Is there a reason for this choice on the part of PHP language designers? As far as I can tell, switch
isn't a looping control structure, so why treat it like one in this case?
@underscore_d A switch statement is neither a conditional nor a loop. It is a way of selecting part of a block of code for execution. This is addressed in the answer.
A switch statement is a loop structure that allows a program code to choose the code to run from a wide range of available code, based on which condition is met. A switch is most valued when there are a lot of optional code blocks needed to be chosen from.
A switch is faster in that situation, because a loop would check the end condition several times, whereas a switch does it only once. This is called loop unrolling, and optimising compilers largely do it on their own.
"Note that in PHP the switch statement is considered a looping structure for the purposes of continue." So the use of continue will break out of the switch statement, not the for loop.
The best explanation I can think of is that PHP considers it a looping structure so it fits the model of something that uses continue
and break
. The switch
documentation doesn't shed much further light on it other than
Note that unlike some other languages, the continue statement applies to switch and acts similar to break. If you have a switch inside a loop and wish to continue to the next iteration of the outer loop, use continue 2.
So perhaps it is because, like a loop, it stops the execution of the rest of the code in its structure.
However, when you use a number of levels, these two behave quite differently:
continue
without a level
<?php
for($i=0;$i<5;$i++) {
switch($i) {
case 2:
continue;
default:
echo $i, "\n";
}
echo "Finished with {$i}\n";
}
//0
//Finished with 0
//1
//Finished with 1
//Finished with 2
//3
//Finished with 3
//4
//Finished with 4
continue
with a level
<?php
for($i=0;$i<5;$i++) {
switch($i) {
case 2:
continue 2;
default:
echo $i, "\n";
}
echo "Finished with {$i}\n";
}
//0
//Finished with 0
//1
//Finished with 1
//3
//Finished with 3
//4
//Finished with 4
break
without a level
<?php
for($i=0;$i<5;$i++) {
switch($i) {
case 2:
break;
default:
echo $i, "\n";
}
echo "Finished with {$i}\n";
}
//0
//Finished with 0
//1
//Finished with 1
//Finished with 2
//3
//Finished with 3
//4
//Finished with 4
break
with a level
<?php
for($i=0;$i<5;$i++) {
switch($i) {
case 2:
break 2;
default:
echo $i, "\n";
}
echo "Finished with {$i}\n";
}
//0
//Finished with 0
//1
//Finished with 1
I think you won't find any real "reason" for this behavior.
The only real motivation behind this behavior was probably that implementing switch
as if it were a looping structure allows PHP to reuse existing break
and continue
semantics of loops instead of reimplementing a special version for switch
.
Or to phrase it more positively: It's for consistency.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With