if (condition) { /* do something */ }
else { /* do something */ }
if (condition)
/* do something */
else
/* do something */
I was told that the first instance wasn't a good idea. I have no idea whether this is really this case (or for the second one either); does it not shorten the amount to type? Or is it because it just makes a mess?
The best practice is to write code that others can read and update easily.
Your first form is questionable because it doesn't follow the forms that most PHP developers are used to:
if (condition) {
// code
} else {
// code
}
// ... or ...
if (condition)
{
// code
}
else
{
// code
}
// ... or ...
if (condition) { /* short code */ } else { /* short code */ }
// ... or ...
condition ? /* short code */ : /* short code */;
Note that this is entirely about standard practice, and doesn't necessarily make sense—it's only about what other developers are used to seeing.
Your second form, more importantly, isn't so good because it makes it easy for another programmer to make this mistake:
if (condition)
// code A
else
// code B
// code C (added by another programmer)
In this example, the other programmer added code C, but forgot to wrap the whole else block in braces. This will cause problems. You can defend against this by simply wrapping your if and else blocks in braces.
My preference if for consistency... so:
if(...)
{
statement 1;
statement 2;
}
else
{
statement 1;
statement 2;
}
is no different than:
if(...)
{
statement 1;
}
else
{
statement 1;
}
So I always use them because it is consistent and it avoids problems forgetting to add them in later.
However other people will look at my code and think that it is stupid to put in the { and }. They have their reasons, I have mine... I happen to like my reasons more than I like theirs :-)
Generally non-readable code is a bad practice. The single line is more efficient in your typing and saves line numbers but come back to it a year from now or while you're scanning for bugs and it'll make it more difficult.
In my opinion, yes it's bad practice to have single line if statements.
The computer doesn't really care (as far as I can tell) but you should always write your code like it's going to be maintained by a serial killer that knows where you live.
Readable! Easily self-discernable.
The problem I've seen is developers not recognizing the {}-less-if when they add code to one of the conditions. Example:
//before
if(something)
statement;
//after
if(something)
statement;
addedstatement;
Obviously, this won't do what they expect.
Have you ever seen code like this in C or C++?
/* Warning: bogus C code! */
if (some condition)
if (another condition)
do_something(fancy);
else
this_sucks(badluck);
Either the indentation is wrong, or the program is buggy, because an "else" always applies to the nearest "if", unless you use braces.
(Let's just use python. No brackets, just pure clean whitespaces. :P)
For all but the shortest statements, use the braces and space them accordingly. You want to do this for a few reasons:
It's harder to make a mistake about where something goes.
It's easier to read.
In languages with macro-expansion facilities (e.g. C, C++), failure to include braces will cause confusing logic errors when a macro containing multiple statements is expanded inside of an unbraced if-else.
One major benefit of using multiple lines is ease of debugging. If you have an if else statement all on one line and the debugger tells you that line x blew up, it's more difficult to determine which part of the statement failed. Multiple lines also makes it easier to step through your code using a debugger.
Those are two lines long, so not really a single line.
There's nothing wrong with single line ifs when it makes the code easier to read.
For example, something like this:
if (last_item) print ", and " else print ", "
is much better than
if (last_iem)
{
print ", and "
}
else
{
print ", "
}
This is more coding style than anything else. That said, my personal opinion is that your second example is potentially quite harmful. It's easy enough to accidentally "add a second line to the block" in languages where braces are the only way to create blocks. But in PHP, where an alternate syntax exists, this is even less likely to set off the necessary warning bells:
if ($_GET["asdf"]==1):
/* do something */
else:
/* do something */
endif;
Rule of thumb: if you're going to put your "do something" on a separate line, use braces; if you're not going to use braces, put it on the same line!
I have seen so many third party code with silly issues, that I prefer to use braces all the time. That said I have never felt good on
if(){}
else (){}
I use if(){} on the same line when it is a short instruction and it is alone. If there is an else use the long:
if(checkSomething)
{
//dosomething
}
else
{
//doanotherthing
}
This is something that I actually remember from an employment exam a while back. The code was similar to the following:
if (x == 0)
x = 2;
else
print("x is: %d", x); // debugging!
x = 4;
Most people here can spot the error, but you can really substitute in anything you want as the "bad code" that was inserted. The more subtle error comes when you have an "old version" of something commented out, and somebody un-comments it, and suddenly the second statement is outside the block.
Basically, unless it's a small test application to learn a concept fast, I always bracket (and even in the test apps I usually bracket). It just isn't worth the headache later if I don't, even in 5-line-methods.
You should put the "if" and the "do something" on separate lines to make your code friendlier to interactive debuggers.
If you put both the "if" and "do something" on the same line, then you can't set a breakpoint just on the "do something" line.
Related
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 12 years ago.
It occurs to me that there are number of different ways to structure conditional logic. As far as I can see, as long as we set errors to end the script (or you can imagine the same examples but with a return in a function), then the following examples are equal:
Example 1
if($condition1) {
trigger_error("The script is now terminated");
}
if($condition2) {
trigger_error("The script is now terminated");
}
echo "If either condition was true, we won't see this printed";
Example 2
if(!$condition1) {
if(!$condition2) {
echo "If either condition was true, we won't see this printed";
}
else {
trigger_error("The script is now terminated");
}
}
else {
trigger_error("The script is now terminated");
}
Example 3
if($condition1) {
trigger_error("The script is now terminated");
}
else {
if($condition2) {
trigger_error("The script is now terminated");
}
else {
echo "If either condition was true, we won't see this printed";
}
}
Example 4 -- Adapted from Fraser's Answer
function test($condition) {
if($condition) {
trigger_error("The script is now terminated");
}
}
test($condition1);
test($condition2);
echo "If either condition was true, we won't see this printed";
Personally, I lean towards writing code as in Example 1. This is because I feel that by checking for conditions that end the script (or function) in this way, I can clearly define what the script executed and not executed i.e. everything before the condition has been executed and everything after the line has not. This means when I get an error on line 147, I know immediately what has happened helping me to find a bug faster. Furthermore, if I suddenly realise I need to test $condition2 before $condition1, I can make a change by a simple copy paste.
I see a lot of code written like in Example 2 but for me, this seems much more complex to debug. This is because, when the nesting gets too great, an error will get fired off at some distant line at the bottom and be separated from the condition that caused it by a huge chunk of nested code. Additionally, altering the conditional sequence can be a lot messier.
You could hybrid the two styles, such as in Example 3, but this then seems to overcomplicate matters because all of the 'else's are essentially redundant.
Am I missing something? What is the best way to structure my conditional code? Is there a better way than these examples? Are there specific situations under which one style may be superior to another?
Edit: Example 4 looks quite interesting and is not something I had considered. You could also pass in an error message as a second parameter.
Thanks!
P.S. Please keep in mind that I might need to do some arbitrary steps inbetween checking $condition1 and $condition2 so any alternatives must accommodate that. Otherwise, there are trivially better alternatives such as if($condition1 || $condition2).
I am in the Example 1 camp. As a rule of thumb, the less indentation needed, the better.
// Exit early if there are errors.
if ($n < 0) {
die "bad n: $n";
}
// Handle trivial cases without fuss.
if ($n == 0) {
return 0;
}
/* Now the meat of the function. */
$widget->frob($n);
foreach ($widget->blaxes as $blax) {
checkFrobbingStatus($blax);
}
// ...And another 20 lines of code.
When you use an if/else and put the success and error code in parallel sections you make it appear as if the two code blocks are equal. In reality, the edge cases and error conditions should be de-emphasized. By intentionally handling errors early and then not putting the "important" code in an else clause I feel like that makes it visually clearer where the important code is.
"Here are all the preconditions. And now here's the good stuff."
Personally I hate nested if-else statements so #1 for me from your examples. The other option I would look at is something like the following.
function test($condition) {
if($condition) {
trigger_error("The script is now terminated");
}
}
test($condition1);
//do stuff...
test($condition2);
//passed the tests
EDIT: The more I think about it a functional approach is by far the best way in that it negates having to write the logic that tests the conditions more than once. It also allows greater readability because it is obvious you are 'testing' the condition (as long as you give the function a meaningful name). Also, as pointed out in the question edit it would be trivial to pass other parameters to the function. i.e.
function test($c, $msg) {
if($c) {
trigger_error($msg);
}
}
test($condition1, "condition1 error");
test($condition2, "condition2 error");
#1 is by far the clearest. However, if somehow the thing that previously ended the execution were changed to do something else, then it would break.
It's still probably best to go with #1, but make sure the thing being used to "stop" is clearly named to indicate that it does stop things, so that someone in 10 years maintaining your code doesn't accidentally break things by changing it.
I think your method (example 1) is the most efficient and effective in this type of situation. However, there are times when you do not want any conditions to halt execution and you only want to execute condition2 if condition1 is false. In these situations, an else or elseif works well.
I suggest using ‘try‘ clause over any part that can have errors and use ‘throw "error description"‘ each time an error occures(like example #1).
That way you can have error reporting code once in your program (in the ‘catch‘ clause) and splitting code into functions won't be a hussle rewriting error handlig.
I prefer this style, which doesn't break if either of the conditional blocks are changed so they do not exit execution.
if($condition1) {
trigger_error("The script is now terminated");
}
if($condition2) {
trigger_error("The script is now terminated");
}
if (!$condition1 && !$condition2) {
echo "If either condition was true, we won't see this printed";
}
Edit: Missed the PS, so updated code to match the full question details.
I generally agree with Amber insofar as your first option seems the most legible. This is something I have fought with myself - thus far the only reasoning I have stumbled across is as follows:
The first form is clearest when reading through a linear script, so ideal for simple scripts
The second form is cleanest when you need to ensure tidy / clean-up operations
I mention the second because this is a sticky point. Each script may be part of a larger system, and in fact the script elements you are injecting the "bail out" code into may be called by multiple places. Throw in some OO and you've got a real potential pickle.
The best rule of thumb I can recommend is that if your scripts are simple and linear, or your are doing rapid prototyping, then you want to use the first form and just kill the execution at that point. Anything more complicated or "enterprise-esque" will benefit from (at least) a modular redesign so you can isolate the method and the call stack - and possibly encapsulation of an OO build.
With some of the more powerful debugging and tracing tools which are available these days, it is becoming more a matter of personal style than necessity. One other option you might consider is to put information in comments before (and possibly after) each bail-out zone which make it clear what the alternative is should the criteria be met (or failed).
Edit:
I'd say Fraser's answer is the cleanest for encapsulation. The only thing I would add it that you might benefit from passing an object or hash array into the standard "bail out, I'm dead" method so you can modify the information made available to the function without changing parameter lists all the time (very annoying...).
That said - be careful in production systems where you may need to clean up resources in an intermediate state.
I much prefer #1 as well.
In addition, I really like to assign variables during the conditionals
e.g.
if ( !$userName = $user->login() ) {
die('could not log in');
}
echo "Welcome, $username";
I usually find that in the first write of code, I end up with a fair few messy nested conditional statements, so it's usually during a second pass that I go back and clean things up, un-nest as many of the conditionals that I can.
In addition to looking much neater, I find it conceptually much easier to understand code where you don't have to mentally keep track of branching logic.
For branching logic that can't be removed that contains lots of procedural code, I usually end up putting it in a function / class method -- ideally so I can see on one screen all the branching logic that is taking place, but modifying either the actions or the logic won't break the other one.
Example 5
if($condition1 || $condition2)
{
echo "If either condition was true, we won't see this printed";
}else
{
trigger_error("The script is now terminated");
}
Example 6
function allAreTrue()
{
foreach(func_get_args() as $check)
{
if(!$check)
{
return false;
}
}
return true;
}
if(allAreTrue(true,true,$condition1,$condition2,false))
{
exit("Invalid Arguments");
}
//Continue
The best way to structure conditional logic is to follow the logic itself.
If you have dependencies, say, failing of first condition will make others unnecessary is one thing. Then return, goto, nested conditions and exceptions at your choice.
If you are about to make decision upon a test, say
if (!isset($_GET['id'])) {
//listing part:
} else {
// form displaying part:
}
it's else, elseif and case realm.
etc.
Determine your program logic first and write it's logic then.
and trigger_error() has nothing to do with conditions. It is debugging feature, not program logic related one.
I've never been a fan of brackets in control structures and only today I realised how it only accepts one statement within a bracket less if condition, if I have more than one statement it will throw a syntax error. Is this how PHP works or can it be something wrong with my IDE?
Obviously the error is clear but I just want to make sure this is normal.
If you have any other any links to other alternate syntax let me know please.
Bellow is just something I pasted from a project am doing and example of the syntax error.
if($this->reel3 = 1)
parent::addCash($this->$bet*2);
print(parent::getCash()); // < Line throwing the syntax error
else
// TODO
EDIT (FURTHERMORE)
After looking at some of the answer and comments I was wondering how its done in a professional environment, I know this is more about taste but I want to know from the professional out there if the style of the syntax matters?
Would
if(condition)
{
//something
} else {
//something
}
be better than
if(condition):
//something
else:
//something
endif;
or any other way of writing the same piece of code?
This is how php works. If you don't put brackets around your if statement only the next statement is in the if block all other follow up statements are outside of it. But since you have a else block after it you will get a error.
(BTW: You make an assignment in the if block, so this will be always true)
Look at these 2 examples:
if($this->reel3 = 1)
parent::addCash($this->$bet*2); //In the if statement
print(parent::getCash()); //Outside the if statement
else
Same as:
if($this->reel3 = 1) {
parent::addCash($this->$bet*2);
}
print(parent::getCash());
//^^^^^ I think here it's more clear to see that this will give you a error, since it's between the if and else block which is not allowed
else { }
For more information about the control structure if see the manual: http://php.net/manual/en/control-structures.if.php
Take a look at the answer of this question:
PHP conditionals, brackets needed?
And yes, it is PHP, not your IDE!
This is perfectly normal of all programming languages that use brackets rather than indentation to designate blocks of code. Without the brackets, there is no way for the interpreter to know which lines are part of the if block and which aren't. The one-line if-block is a convenient shortcut: if you don't include any brackets, PHP like many other languages will treat the single line directly following the if statement as the body of the if block.
Note PHP does have an alternative syntax for if statements as well, using colons instead of brackets, but that's a story for another day.
if I have code like that
if($abc==true) {
//code code code
} else {
// other code, other code
}
So if $abc is true will the "other code" be compiled?
So is this irrelevant if there is a lot of "code" performance wise?
PHP is a parsed (and therefore "compiled") at runtime. All of the code is processed, regardless of reachability. For instance:
<?php
echo "Hello, World!";
exit;
DERP!!
?>
Will fail with a Parse Error rather than printing "Hello, World!", even though the derp can't ever be reached.
Yes, it will be compiled (actually read, tokenized and parsed); PHP has no way of knowing what value will be assumed by $abc at runtime.
You can reduce the load somewhat (but only if it is REALLY a lot of code!) by using include() inside the IFs:
if (condition)
{
include('true.php');
}
else
{
include('false.php');
}
But note that this way you will load two files instead of one. Usually, the overhead of the extra file makes the game not worth the effort.
However, if the IF is really a lot lot lot of code, then dividing it in several files might be a good idea maintenance-wise. Refactoring to remove the IF from the program flow would be even better!
Although the entire code is 'parsed' for errors at runtime, the flow of code will only go in one direction at that 'if' point, so there's basically no speed performance issue.
It's really not worth worrying about, especially since flow control statements such as 'if' are probably the most vital elements of programming. You can't get by without them, really.
What performance problems are you concerned about? PHP is an interpreted language which means your files are parsed, tokenized, and executed on every request. The entire file needs to be parsed and tokenized for syntax errors no matter what. What is executed depends on your control flow statements, like the if in your example.
If you're concerned about extra parsing, you can refactor your code to include another file based on the result of a control flow statement.
$x = 1;
if($x === 1) {
include_once './myFile.php';
}
else {
// Something Else.
}
Though I can't really think of a huge reason related to performance as to why you would want to do that.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 12 years ago.
It occurs to me that there are number of different ways to structure conditional logic. As far as I can see, as long as we set errors to end the script (or you can imagine the same examples but with a return in a function), then the following examples are equal:
Example 1
if($condition1) {
trigger_error("The script is now terminated");
}
if($condition2) {
trigger_error("The script is now terminated");
}
echo "If either condition was true, we won't see this printed";
Example 2
if(!$condition1) {
if(!$condition2) {
echo "If either condition was true, we won't see this printed";
}
else {
trigger_error("The script is now terminated");
}
}
else {
trigger_error("The script is now terminated");
}
Example 3
if($condition1) {
trigger_error("The script is now terminated");
}
else {
if($condition2) {
trigger_error("The script is now terminated");
}
else {
echo "If either condition was true, we won't see this printed";
}
}
Example 4 -- Adapted from Fraser's Answer
function test($condition) {
if($condition) {
trigger_error("The script is now terminated");
}
}
test($condition1);
test($condition2);
echo "If either condition was true, we won't see this printed";
Personally, I lean towards writing code as in Example 1. This is because I feel that by checking for conditions that end the script (or function) in this way, I can clearly define what the script executed and not executed i.e. everything before the condition has been executed and everything after the line has not. This means when I get an error on line 147, I know immediately what has happened helping me to find a bug faster. Furthermore, if I suddenly realise I need to test $condition2 before $condition1, I can make a change by a simple copy paste.
I see a lot of code written like in Example 2 but for me, this seems much more complex to debug. This is because, when the nesting gets too great, an error will get fired off at some distant line at the bottom and be separated from the condition that caused it by a huge chunk of nested code. Additionally, altering the conditional sequence can be a lot messier.
You could hybrid the two styles, such as in Example 3, but this then seems to overcomplicate matters because all of the 'else's are essentially redundant.
Am I missing something? What is the best way to structure my conditional code? Is there a better way than these examples? Are there specific situations under which one style may be superior to another?
Edit: Example 4 looks quite interesting and is not something I had considered. You could also pass in an error message as a second parameter.
Thanks!
P.S. Please keep in mind that I might need to do some arbitrary steps inbetween checking $condition1 and $condition2 so any alternatives must accommodate that. Otherwise, there are trivially better alternatives such as if($condition1 || $condition2).
I am in the Example 1 camp. As a rule of thumb, the less indentation needed, the better.
// Exit early if there are errors.
if ($n < 0) {
die "bad n: $n";
}
// Handle trivial cases without fuss.
if ($n == 0) {
return 0;
}
/* Now the meat of the function. */
$widget->frob($n);
foreach ($widget->blaxes as $blax) {
checkFrobbingStatus($blax);
}
// ...And another 20 lines of code.
When you use an if/else and put the success and error code in parallel sections you make it appear as if the two code blocks are equal. In reality, the edge cases and error conditions should be de-emphasized. By intentionally handling errors early and then not putting the "important" code in an else clause I feel like that makes it visually clearer where the important code is.
"Here are all the preconditions. And now here's the good stuff."
Personally I hate nested if-else statements so #1 for me from your examples. The other option I would look at is something like the following.
function test($condition) {
if($condition) {
trigger_error("The script is now terminated");
}
}
test($condition1);
//do stuff...
test($condition2);
//passed the tests
EDIT: The more I think about it a functional approach is by far the best way in that it negates having to write the logic that tests the conditions more than once. It also allows greater readability because it is obvious you are 'testing' the condition (as long as you give the function a meaningful name). Also, as pointed out in the question edit it would be trivial to pass other parameters to the function. i.e.
function test($c, $msg) {
if($c) {
trigger_error($msg);
}
}
test($condition1, "condition1 error");
test($condition2, "condition2 error");
#1 is by far the clearest. However, if somehow the thing that previously ended the execution were changed to do something else, then it would break.
It's still probably best to go with #1, but make sure the thing being used to "stop" is clearly named to indicate that it does stop things, so that someone in 10 years maintaining your code doesn't accidentally break things by changing it.
I think your method (example 1) is the most efficient and effective in this type of situation. However, there are times when you do not want any conditions to halt execution and you only want to execute condition2 if condition1 is false. In these situations, an else or elseif works well.
I suggest using ‘try‘ clause over any part that can have errors and use ‘throw "error description"‘ each time an error occures(like example #1).
That way you can have error reporting code once in your program (in the ‘catch‘ clause) and splitting code into functions won't be a hussle rewriting error handlig.
I prefer this style, which doesn't break if either of the conditional blocks are changed so they do not exit execution.
if($condition1) {
trigger_error("The script is now terminated");
}
if($condition2) {
trigger_error("The script is now terminated");
}
if (!$condition1 && !$condition2) {
echo "If either condition was true, we won't see this printed";
}
Edit: Missed the PS, so updated code to match the full question details.
I generally agree with Amber insofar as your first option seems the most legible. This is something I have fought with myself - thus far the only reasoning I have stumbled across is as follows:
The first form is clearest when reading through a linear script, so ideal for simple scripts
The second form is cleanest when you need to ensure tidy / clean-up operations
I mention the second because this is a sticky point. Each script may be part of a larger system, and in fact the script elements you are injecting the "bail out" code into may be called by multiple places. Throw in some OO and you've got a real potential pickle.
The best rule of thumb I can recommend is that if your scripts are simple and linear, or your are doing rapid prototyping, then you want to use the first form and just kill the execution at that point. Anything more complicated or "enterprise-esque" will benefit from (at least) a modular redesign so you can isolate the method and the call stack - and possibly encapsulation of an OO build.
With some of the more powerful debugging and tracing tools which are available these days, it is becoming more a matter of personal style than necessity. One other option you might consider is to put information in comments before (and possibly after) each bail-out zone which make it clear what the alternative is should the criteria be met (or failed).
Edit:
I'd say Fraser's answer is the cleanest for encapsulation. The only thing I would add it that you might benefit from passing an object or hash array into the standard "bail out, I'm dead" method so you can modify the information made available to the function without changing parameter lists all the time (very annoying...).
That said - be careful in production systems where you may need to clean up resources in an intermediate state.
I much prefer #1 as well.
In addition, I really like to assign variables during the conditionals
e.g.
if ( !$userName = $user->login() ) {
die('could not log in');
}
echo "Welcome, $username";
I usually find that in the first write of code, I end up with a fair few messy nested conditional statements, so it's usually during a second pass that I go back and clean things up, un-nest as many of the conditionals that I can.
In addition to looking much neater, I find it conceptually much easier to understand code where you don't have to mentally keep track of branching logic.
For branching logic that can't be removed that contains lots of procedural code, I usually end up putting it in a function / class method -- ideally so I can see on one screen all the branching logic that is taking place, but modifying either the actions or the logic won't break the other one.
Example 5
if($condition1 || $condition2)
{
echo "If either condition was true, we won't see this printed";
}else
{
trigger_error("The script is now terminated");
}
Example 6
function allAreTrue()
{
foreach(func_get_args() as $check)
{
if(!$check)
{
return false;
}
}
return true;
}
if(allAreTrue(true,true,$condition1,$condition2,false))
{
exit("Invalid Arguments");
}
//Continue
The best way to structure conditional logic is to follow the logic itself.
If you have dependencies, say, failing of first condition will make others unnecessary is one thing. Then return, goto, nested conditions and exceptions at your choice.
If you are about to make decision upon a test, say
if (!isset($_GET['id'])) {
//listing part:
} else {
// form displaying part:
}
it's else, elseif and case realm.
etc.
Determine your program logic first and write it's logic then.
and trigger_error() has nothing to do with conditions. It is debugging feature, not program logic related one.
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...