Is it good practice to use break and continue in PHP? - php

Is it a good practice to use break and continue as sentinel for loops in PHP?
e.g.
if (!empty($var))
break;

do {
if (condition1)
break;
some code;
some code;
if (condition2)
break;
some code;
some code;
if (condition3)
break;
some code;
some code;
} while (false);
vs.
if (!condition1) {
some code;
some code;
if (!condition2) {
some code;
some code;
if (!condition3) {
some code;
some code;
}
}
Some find the first version an abhomination and difficult to read and love the second version. Some find the first version cleaner and easier to read. As the number of conditions multiply, I tend to find the first version easier to follow, as the second one tends to get more and more difficult to follow the level of nesting. Also if the if (condition) break; gets into something only slightly more complex like if (condition) {some code; break}, the do {if .. break; if .. break..;} while(false) pattern gets even more clear compared with equivalend nested ifs.

In light usage it is ok, but in heavy usage it makes your code spaghetti. break and continue is basically just a restricted goto and as such, use sparingly.

It absolutely is, they're both valid programming constructs.
What is not a good idea is the newly introduced GOTO. (Please tell me this was an April fool's joke I didn't see the note about!)

It is perfectly correct to use break or continue as long as it helps to make the code easier to read and understand. I personally use them very rarely, and only when I cannot easily use another structure.
In the case of most while statements, it's easier to achieve the same result as a break or continue by using a boolean variable as the condition for the loop in the first place, and then modifying its value inside the loop.
On the other hand, the best use case for the break, in my opinion, is to save resources if you are iterating through an array or something similar with a for or foreach block and are only interested in processing elements until some item is reached. By using a break after reaching this element, it is possible to save on processing power by breaking out of the loop without going over the remaining elements. This makes the code more efficient without making it less legible.
And of course, it is practically impossible to use switch statements without break.
Another exception is if you need to control nested structures, in which case it is sometimes simpler to use break n or continue n than manipulate multiple variables concurrently. (Even though this use case is probably the most controversial...)

In Python, we use infinite loop and break to improve readability. So yes, you can use it, provided you do it correctly, and for a good reason.

Let me answer with a couple of questions:
Why shouldn't it be considered good practice?
Does it reduce readability of your code?
Does it slow down your for cycles?

For a discussion of break and continue in PHP (and looping in general) have a look at Advanced loops - you get the impression that the author can just about manage to swallow break and continue but not break n and continue n. :-)

In 5+ years programming PHP I never had to use break outside of switch statements.
Continue is sometimes used to skip first or last items in iterations, but I don't like it very much.
Why did they reintroduce GOTO ? that's a shame
To answer the question, in
if (!empty($var))
break;
Why not use return (if in a method context)
if (!empty($var))
return false;
I think this way much clear and makes the caller aware of what's happened inside. A better use for argument errors is using Excecptions, which in facte will break execution a the point they are raised.

Related

PHP - Faster to use code

In general, is code length affective to the speed of the program? I'm talking about differences in small sizes not comparing 10,000 lines to 10.
Example #1:
// Ternary Operator
$todo = (empty($_POST['todo'])) ? 'default' : $_POST['todo'];
VS
// The above is identical to this if/else statement
if (empty($_POST['todo'])) {
$action = 'default';
} else {
$action = $_POST['todo'];
}
And other examples like not using common brackets and universal indentation.
Example #2:
if ($gollum === 'halfling') {
$height --;
}
VS
if ($gollum === 'halfling') $height --;
Also using CamelCase naming convention will lower the characters length, is that effective at all? I doubt this is effective, but still it uses less characters.
Cheers!
In your first example, you are using two different constructs, namely the 'ternary operator' and an 'if / else' statement.
Since the 'if / else' statement is more general (ie you can do more thing with it), the compiler / parser will have more difficulties to optimize it. So I would say that the ternary operator might be a little bit faster.
In the second example, it is only about coding style, both codes will probably be compiled / parsed to exactly the same thing, so no gain here.
However, premature optimization is the root of all evil ! The gain from doing such micro tiny optimization, even on a whole application will probably be negligible and will most of the time be at the expense of readability and maintainability. So I would strongly advice against that kind of thing.
Concerning characters length, it won't matter at all, the compiler / parser will transform that anyway to some other representation that could be understood by the computer, so the only thing that will change is the space that your source code will take on the hard drive.
Just write your code the way it is easier for you to understand and let the compiler / parser do those kind of thing. It is much better to optimize the algorithm itself than the way of writing it.
I think you shoud concern coding style more than efficiency now.
if you already have a style guide, follow it. if you not, you can find one or create one. There aren't such difference between your codes both of two examples. You can pick anyone to create your own style guide.

If a switch matches multiple cases will all matching cases run?

I'm attempting to go through a large number bitwise tests, 32 to be exact, where there could be multiple matches. The only method I can think of that would work is to use a whole long list of if statements, e.g.
$test = 3;
if(($test & 1) == 1) {
do something...
}
if(($test & 2) == 2) {
do something else...
}
The other possibility I was thinking of to cut down on the code, although probably not by much is a switch statement. That said, I'm not even sure if what I am thinking of will even work:
$test = 3;
switch($test) {
case ((1 & $test) == 1):
do something...
break;
case ((2 & $test) == 2):
//Will this run?
do something else...
break;
}
Will the break end the switch? Or will the switch continue and each case run that the bitwise operation returns true?
I ask because my actual program will have 32 different tests, and I don't want to write all 32 just to find it doesn't work and Google hasn't turned up anything on this.
If this doesn't work is there a solution that will, or am I relegated to a large number of if statements?
No this is not the case. Only one of the switch cases will run in your example. As soon as break is encountered the switch processing ends. Only one branch will match. In PHP I think (but you might want to double check) the first matching case will run.
With multiple possible matches you will need to use a set of if statements (note do not use if...elseif)
I would convert to
if($test & 1) {
// do stuff
}
if(test & 2) {
// do stuff
}
Well first, using switch with int this way is not really recommended. It's not a good practice / not really readable / not comfortable. I would say it does not even work, although I have a doubt now... depending on versions and stuff, I'm not aware enough of these things.
Then, to answer your question, you only go inside the first matching case... then the break makes you leave the switch. However, you can omit the break and it will go through the second case.
Anyway, you should make more use of OOP to characterize better what you intend to do, and things will probably get more simple and clearer.

What is the benefit of using multiple steps to complete an if test?

What is the benefit of using multiple steps to test variables:
$VarLength = strlen($message);
if ($VarLength > 10)
echo "Over Ten";
...versus just pushing the whole process into one if statement:
if ( strlen($message) > 10 )
echo "Over Ten";
I'm wondering if the benefits go beyond code style, and the ability to re-use the results of the (in the example above) strlen result.
Your question is not really possible to answer technically, so this is more a comment than an answer.
Benefits beyond code-style and re-use of the result is when you change the code.
You might want to replace the strlen() function with some other function but you don't want to edit the line with the if clause while you do so. E.g. to prevent errors or side-effects. That could be a benefit, however it depends on code-style somehow. So as you exclude coding style from your question, it makes it hard to answer as that domain touches a lot how you can/should/would/want/must write code.
If the result of a function will be used multiple times, it should be cached in a variable so as to obviate the need to waste resources to re-calculate its result.
If the function result won't be re-used, it can simply be a matter of code readability to clearly delineate what's happening by storing the function return value in a variable before using it in an if condition.
Also, in terms of readability, you should always use curly braces even when not mandated by PHP syntax rules as #AlexHowansky mentions.
Most of it is in the code style. In terms of rapidity of the results, it doesn't change much. If you are using $varLenght more then once, then you are saving the call to the function to obtain the length. But even that, the time difference is extremely minimal (I would even like to say unnoticable).
But: When developping any applications, you have to keep in mind that you might not be the only one making changes to it down the road, or you might not be as fresh and up to date with the exact program you are writing. Therefore, the cleaner the code, the easier it is in terms of maintenance, and THAT'S where you save a lot of time down the road.
Best Practice dictates that functions be called minimally. In your case the practice doesn't violate the rule, but it is not uncommon to find code like:
if ( strlen($message) > 100 )
echo "Over Ten";
else if ( strlen($message) > 20 )
echo "Over Ten";
else if ( strlen($message) > 10 )
echo "Over Ten";
...
A common prevention is to always assign function results to a variable for consistency.
I wouldn't say there is any benefit apart from the re-use case you've already mentioned. Your latter case is more readable, probably faster, and probably less memory-intensive. I would however strongly recommend always using braces, even when your conditional is only one line:
if (condition) {
statement;
}

Is there an automated way of fixing one line ifs in PHP?

I don't know if it's just me or not, but I am allergic to one line ifs in any c like language, I always like to see curly brackets after an if, so instead of
if($a==1)
$b = 2;
or
if($a==1) $b = 2;
I'd like to see
if($a==1){
$b = 2;
}
I guess I can support my preference by arguing that the first one is more prone to errors, and it has less readability.
My problem right now is that I'm working on a code that is packed with these one line ifs, I was wondering if there is some sort of utility that will help me correct these ifs, some sort of php code beautifier that would do this.
I was also thinking of developing some sort of regex that could be used with linux's sed command, to accomplish this, but I'm not sure if that's even possible given that the regex should match one line ifs, and wrap them with curley brackets, so the logic would be to find an if and the conditional statement, and then look for { following the condition, if not found then wrap the next line, or the next set of characters before a line break and then wrap it with { and }
What do you think?
Your best bet is probably to use the built-in PHP tokenizer, and to parse the resulting token stream.
See this answer for more information about the PHP Tokenizer: https://stackoverflow.com/a/5642653/1005039
You can also take a look at a script I wrote to parse PHP source files to fix another common problem in legacy code, namely to fix unquoted array indexes:
https://github.com/GustavBertram/php-array-index-fixer/blob/master/aif.php
The script uses a state machine instead of a generalized parser, but in your case it might be good enough.

GOTO command in PHP?

I've heard rumors that PHP is planning on introducing a "goto" command. What is it supposed to be doing?
I've tried searching a bit, but haven't found anything awfully descriptive. I understand that it won't be a "GOTO 10"-like command...
They are not adding a real GOTO, but extending the BREAK keyword to use static labels. Basically, it will be enhancing the ability to break out of switch nested if statements. Here's the concept example I found:
<?php
for ($i = 0; $i < 9; $i++) {
if (true) {
break blah;
}
echo "not shown";
blah:
echo "iteration $i\n";
}
?>
Of course, once the GOTO "rumor" was out, there was nothing to stop some evil guys to propagate an additional COMEFROM joke. Be on your toes.
See also:
http://www.php.net/~derick/meeting-notes.html#adding-goto
I'm always astonished at how incredibly dumb the PHP designers are.
If the purpose of using GOTOs is to make breaking out of multiply nested
loops more efficient there's a better way: labelled code blocks
and break statements that can reference labels:
a: for (...) {
b: for (...) {
c: for (...) {
...
break a;
}
}
}
Now is is clear which loop/block to exit, and the exit is structured;
you can't get spaghetti code with this like you can with real gotos.
This is an old, old, old idea. Designing good control flow management
structures has been solved since the 70s, and the literature on all this
is long since written up. The Bohm-Jacopini theorem showed that
you could code anything with function call, if-then-else, and while loops.
In practice, to break out of deeply nested blocks, Bohm-Jacopini style
coding required extra boolean flags ("set this flag to get out of the loop")
which was clumsy coding wise and inefficient (you don't want such flags
in your inner loop). With if-then-else, various loops (while,for)
and break-to-labelled block, you can code any algorithm without no
loss in efficiency. Why don't people read the literature, instead
of copying what C did? Grrr.
Granted, I am not a PHP programmer, and I don't know what PHP's exact implementation of GOTO will look like, but here is my understanding of GOTO:
GOTO is just a more explicit flow control statement like any other. Let's say you have some nested loops and you only need to find one thing. You can put in a conditional statement (or several) and when conditions are met properly, you can use a GOTO statement to get out of all the loops, (instead of having a 'break' statement at each level of nesting with a conditional statement for each. And yes, I believe the traditional implementation is to have named labels that the GOTO statement can jump to by name. You can do something like this:
for(...) {
for (...) {
for (...) {
// some code
if (x) GOTO outside;
}
}
}
:outside
This is a simpler (and more efficient) implementation than without GOTO statements. The equivalent would be:
for(...) {
for (...) {
for (...) {
// some code
if (x) break;
}
if(x) break;
}
if(x) break;
}
In the second case (which is common practice) there are three conditional statements, which is obviously slower than just having one. So, for optimization/simplification reasons, you might want to use GOTO statements in tightly nested loops.
In the example given by steveth45 you can use a function instead:
function findItem(...) {
for (...) {
for (...) {
for (...) {
if (x) {
return theItem;
}
}
}
}
}
// no need for label now
theItem = findItem(a, b, c);
It looks like it's currently in PHP 5.3, but is not fully documented yet. From what I can tell it shares its goto syntax with C, so it should be easy to pick up and use. Just remember Dijkstra's warning and use it only when necessary.
#steveth45
My rule of thumb is that if you have nested code more than 3 levels deep, you are doing
something wrong.
Then you don't have to worry about using multiple break statements or goto :D
there is a goto in php -> http://php.net/manual/en/control-structures.goto.php, but i wouldn't use it, just write normal code...

Categories