How to correctly format PHP 'IF ELSE' statements? - php

It's been a long running issue that I've come across in many-a-hot-and-steamy coding sessions.
One person codes this way another codes that way. So after much push and pull I'm curious...
Is there any correct way of phrasing a PHP 'IF ELSE' statement?
Personally I use the:
if ($variable == 'setvalue')
{
$variable = executefunctiononvariable($variable);
} else {
$variable = executedifferentfunctiononvariable($variable);
}
After many arguments though I've been presented with other options such as:
if ($variable == 'setvalue')
{
$variable = executefunctiononvariable($variable);
}
else
{
$variable = executedifferentfunctiononvariable($variable);
}
OR
if ($variable == 'setvalue')
$variable = executefunctiononvariable($variable);
else
$variable = executedifferentfunctiononvariable($variable);
OR
if ($variable == 'setvalue') {
$variable = executefunctiononvariable($variable);
} else {
$variable = executedifferentfunctiononvariable($variable);
}

I personally format my if/else like the last one:
if ($variable == 'setvalue') {
$variable = executefunctiononvariable($variable);
} else {
$variable = executedifferentfunctiononvariable($variable);
}
Your version is kind a mixture of 1 and 3, in my mind.
I have also worked with coders that do all of them and have never heard of a standard one.
The php website uses the last one: http://ca2.php.net/manual/en/control-structures.elseif.php
I also use the second example in some cases when the if statement will always be very short. If there's ever a possibiltiy of it getting longer (more than 1 line each) I'll do #1. I try to avoid #2 when possible cause it's hard to add the {} later.

I use the last one:
if ($variable == 'setvalue') {
$variable = executefunctiononvariable($variable);
} else {
$variable = executedifferentfunctiononvariable($variable);
}
That being said, it is pretty unimportant which one you go with, just make sure you are consistent.

The Right Way is to follow your project's coding standard. If you don't have one, adopt one from PHP-FIG, Zend, Symfony, etc.
This form appears very popular:
if (condition) {
statements
} else {
statements
}
For variable assignment I'll use a ternary only if the statement can fit legibly on one line:
$variable = !empty($foo) ? $foo : 'default';
Update: I've removed the bit about a multi-line ternary statements as I no longer consider this a wise practice.

I personnally prefer:
if(something){
doSomething();
}
elseif(somethingElse){
doSomethingElse();
}
else{
doAnotherThing();
}

Don't forget about
if (expression):
// code goes here
elseif (another expression):
// code goes here
else:
// code goes here
endif;
I personally like this structure when I'm cooking some tag soup.

The most important thing is that the programmers working on a project pretty much adhere to the same coding guidelines. So have a meeting and pick one or the other, and then stick with it.

I used to do (2) all the time but got it beaten out of me from Java programming as Sun's coding conventions use (4). So now I'm pretty used to (4). I've been doing a bit of C# lately and it seems to use (2) by default (sigh, here we go again).
In PHP from habit I do (4) but (2) is fine too. I don't like (1) at all.
And (3) is dangerous. Personally I think braces should be required by the syntax of the langauge even if its just for one statement. Saves you getting into trouble. I think that's how Perl does it from memory.
What I also hate is when people do this:
if (something) {
// do something
}
else if (something else) {
}
That one drives me batty. So I only find (2) and (4) acceptable. I don't care which one it is, as long as it's done consistently, preferably within the conventions for the language.

There is no right or wrong way, it is an opinion. Personally, I like the last one best (1TBS???). I never use the one without braces, I consider it bad style in general.
The only people that can really answer this question for you are the other people that are going to work on the code. It is important that everone agrees to a coding standard. Which standard you choose is less important than the fact that everyone uses it.

The PEAR coding standard is the PHP coding standard. I would recommend to get used to it as you will find it in other projects such as Zend, Doctrine, Symfony, Horde and many, many more.
http://framework.zend.com/manual/en/coding-standard.coding-style.html#coding-standard.coding-style.control-statements.if-else-elseif

In short, the is no correct way of doing. As long as it works, whatever you feel is the best, you can use. You should pick one and then stick to it, it will make your code easier to recognise.
The only thing is, if you don't include the "{" character you are limited to one expression or function.
Also, if you are only looking to define variables you can use the following code:
$variable = (CONDITIONAL STATEMENT) ? "It was true" : "It was false";

At my company we use:
if ($variable == 'setvalue')
{
$variable = executefunctiononvariable($variable);
}
else
{
$variable = executedifferentfunctiononvariable($variable);
}
I doesn't really matter aslong as there is a standard

Really to me... it just doesn't matter. I believe you should be able to read either way without issues. Does it really matter if the curly brace is on a new line or not? Does it really matter if there's a space after the closing parenthesis or not?
As long as the code is done in a such way that there's been at least an attempt at making it readable, I really just don't care.
Is there a correct way? Well if there was, then why do we have options of doing it differently?

Related

what do you recommend to clarify my understanding of my PHP code´s flow

when I use some nested if / else statements, sometimes I get confused if my code logic corresponds to my original idea. I use some simple procedural code, so how can I train my understanding?
Try to split your code up into functions. If you have deeply nested if/else statements then you can probably create well-named functions for both the "if" tests and the resulting logic. For example, change:
if ($something == "a" && $somethingElse == "b") {
// code
}
else if ($whatever > 4) {
// more code
}
else {
// yet more code
}
to
if (condition1True()) {
handleCondition1();
}
else if (condition2True()) {
handleCondition2();
}
else {
handleDefaultCondition();
}
Making your code read more like English means you can more easily understand how it works. You can also split your functionality so that each function only needs to do something simple then compose those functions into higher-level behaviour.
EDIT: Regarding comments, I tend to go for well-named functions and variables rather than copious commenting. If you can read the code without comments then that's ideal, but obviously you will still need comments sometimes. Definitely worth writing Javadoc-style comments for each function detailing the meanings of the arguments and return value, but inline comments in the code are sometimes more hindrance than help.
Comments! Write your original ideas in comments above each if/else block, and then make sure the conditionals for each block match the pseudo code you outlined in the comment. If they do, go back after you're done an re-read the comments - if the logic in them still seems valid, then there's a good chance your code will be good to go. I find it much easier to read comments outlining what a conditional does than to decipher each conditional on the fly. Of course, that means keeping comments up to date as well.
One of the best programmers I've ever met stubbed out functions with comments detailing how the function was supposed to work. He could read it back in plain English to make sure it made sense, and then implementation was, as he said, a simple matter of translation. This may not be for everyone, but it may help you keep focused.
Simplify complex conditionals and inner logic with appropriate function calls. Refactor you code to make it more clear, into small chunks. Use switch statements if appropriate, polymorphism if dealing with similar objects, etc.
Seeing some sample code would help give a more appropriate example, but consider the following contrived example:
if($a.isAnimal && $a.animalIsAlive){
if($a.isDog){
if(!$a.hasHadWalk && date('h') > 6 && date('h') < 20){
getLeash();
attachLeashToCollar();
putOnShoes();
...
}else{
//doNotWalk
}
}else{
//some other stuff here
}
}
could be refactored into
if(canBreathe($a)){
if($a.isDog){
if(shouldWeWalk($a)){
walkDog();
}
}else{
//some other stuff here
}
}
function canBreathe($a){
return $a.isAlive && $a.isAnimal;
}
function walkDog(){
getLeash();
attachLeashToCollar();
putOnShoes();
...
}
function shouldWeWalk($a){
return (!$a.hasHadWalk && date('h') > 6 && date('h') < 20);
}
First make a copy of the PHP file ;-)
Then try to refactor some of the deeply nested conditionals code blocks into their own functions and choose the name of these functions carefully.
That will force you to think about the code.
I think
if (condition1True()) {
handleCondition1();
}
else if (condition2True()) {
handleCondition2();
}
else {
handleDefaultCondition();
}
this variant is more preferable, because of better understanding what program doing.

for each ... break

I feel dirty every time I "break" out of a for-each construct (PHP/Javascript)
So something like this:
// Javascript example
for (object in objectList)
{
if (object.test == true)
{
//do some process on object
break;
}
}
For large objectLists I would go through the hassle building a more elegant solution. But for small lists there is no noticeable performance issue and hence "why not?" It's quick and more importantly easy to understand and follow.
But it just "feels wrong". Kind of like a goto statement.
How do you handle this kind of situation?
I use a break. It's a perfectly cromulent solution.
It's quick and more importantly easy to understand and follow.
Don't feel bad about break. Goto is frowned upon because it's quick and more importantly not easy to understand and follow.
See, the break doesn't bug me at all. Programming is built on goto, and for-break - like all control structures - is merely a special-purpose form of goto meant to improve the readability of your code. Don't ever feel bad about writing readable code!
Now, I do feel dirty about direct comparisons to true, especially when using the type-converting equality operator... Oh yeah. What you've written - if (object.test == true) - is equivalent to writing if (object.test), but requires more thought. If you really want that comparison to only succeed if object.test is both a boolean value and true, then you'd use the strict equality operator (===)... Otherwise, skip it.
For small lists, there's no issue with doing this.
As you mention, you may want to think about a more 'elegant' solution for large lists (especially lists with unknown sizes).
Sometimes it feels wrong, but it's all right. You'll learn to love break in time.
Like you said ""why not?" It's quick and more importantly easy to understand and follow."
Why feel dirty, I see nothing wrong with this.
I think is is easier to read and hence easier to maintain.
It is meant to be like it. Break is designed to jump out of a loop. If you have found what you need in a loop why keep the loop going?
Breaks and continues are not gotos. They are there for a reason. As soon as you're done with a loop structure, get out of the loop.
Now, what I would avoid is very, very deep nesting (a.k.a. the arrowhead design anti-pattern).
if (someCondition)
{
for (thing in collection)
{
if (someOtherCondition)
{
break;
}
}
}
If you are going to do a break, then make sure that you've structure your code so that it's only ever one level deep. Use function calls to keep the iteration as shallow as possible.
if (someCondition)
{
loopThroughCollection(collection);
}
function loopThroughCollection(collection)
{
for (thing in collection)
{
if (someOtherCondition)
{
doSomethingToObject(thing);
break;
}
}
}
function doSomethingToObject(thing)
{
// etc.
}
I really don't see anythign wrong with breaking out of a for loop. Unless you have some sort of hash table, dictionary where you have some sort of key to obtain a value there really is no other way.
I'd use a break statement.
In general there is nothing wrong with the break statement. However your code can become a problem if blocks like these appear in different places of your code base. In this case the break statements are code small for duplicated code.
You can easily extract the search into a reusable function:
function findFirst(objectList, test)
{
for (var key in objectList) {
var value = objectList[key];
if (test(value)) return value;
}
return null;
}
var first = findFirst(objectList, function(object) {
return object.test == true;
}
if (first) {
//do some process on object
}
If you always process the found element in some way you can simplify your code further:
function processFirstMatch(objectList, test, processor) {
var first = findFirst(objectList, test);
if (first) processor(first);
}
processFirst(
objectList,
function(object) {
return object.test == true;
},
function(object) {
//do some process on object
}
}
So you can use the power of the functional features in JavaScript to make your original code much more expressive. As a side effect this will push the break statement out of your regular code base into a helper function.
Perhaps I'm misunderstanding your use-case, but why break at all? I'm assuming you're expecting the test to be true for at most one element in the list?
If there's no performance issue and you want to clean up the code you could always skip the test and the break.
for (object in objectList)
{
//do some process on object
}
That way if you do need to do the process on more than one element your code won't break (pun intended).
Use a
Object object;
int index = 0;
do
{
object = objectList[index];
index++;
}
while (object.test == false)
if breaking from a for loop makes you feel uneasy.
My preference is to simply use a break. It's quick and typically doesn't complicate things.
If you use a for, while, or do while loop, you can use a variable to determine whether or not to continue:
for ($i = 0, $c = true; ($i < 10) && $c; $i++) {
// do stuff
if ($condition) {
$c= false;
}
}
The only way to break from a foreach loop is to break or return.

Should PHP code have spaces before operators?

I've seen a lot of code recently formatted as the following:
A:
if ($var=='test'){
$var=Foo('blah'.$var1);
}else{
// do something
}
Personally I don't like it and would prefer it as:
B:
if ($var == 'test') {
$var = Foo('blah' . $var1);
} else {
// do something
}
I think it's much more readable (note the addition of spaces).
Is there a general preference in the community or is one way better than another?
The most important thing is to follow a standard and stick to it.
That said maybe you can follow Zend's Framework standards and they use spaces. Check C.4.6.
if ($a != 2) {
$a = 2;
}
Hope it helps!
+1 for spaces :)
but that's just my own standard, as long as you are consistent and your code is clear, it should be okay
PHP is much like C in its syntax. As I use both, I tend to follow the same style.
For instance, keywords vs functions:
if ($foo) {
vs
MySuperDuperFunction($foo);
Then you come to a question of indentation:
switch ($bar) {
case CONSTANT:
more_code();
.. is much easier to read as
switch ($bar) {
case CONSTANT:
more_code();
This indicates that the switch and the case are on the same level, which they are. It also helps avoid crazy indentation in yet-to-be-optimal switches.
Your style should illustrate the syntactic sugar of the language you are using. This gets strange with PHP as well as C, because both have forgiving parsers.
If you write something like this:
if($a==2&&b==1&&c>3)
{
I'm going to hunt you down and demand that you pay for my aspirin. The same would go for this:
if (
a==2
&&
b==1
&&
c>3
)
{
... For God sakes man, its not LISP!
It's a matter of convetions that are stablished within your team.
The most famous conventions are Zend Framework and PEAR. You can also create your own, just make sure it is readible.
Personally, I use spaces.
The general advice would be to standardize the code formating, so it meets some best practices, and is widely known, instead of inventing something custom.
PSR-2, the coding style guide would be the best well known approach, accepted by many. here are facts, why it's good to keep the code formatting.

Are singleline if statements or if statements without braces bad practice?

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.

why are assignments in conditions bad?

I am using NetBeans for PHP 6.5.
In my code I frequently use the following type of command:
if (($row = $db->get_row($sql))) {
return $row->folder;
} else {
return FALSE;
}
Netbeans tells me that I should not be using assignments in the IF statement.
Why ?
They are not bad, but they can lead to dangerous mistakes.
In c like languages, where an assignment is an expression, (to support for example a=b=c=1;) a common error is:
if (a = 1) { .. }
But you wanted to have
if (a == 1) { .. }
Some developers have learned to type
if (1 == a) { .. }
To create an error if one '=' is forgotten. But I think that it does not improve the readability.
However modern compilers, give a warning if you write
if (a = 1) { .. }
which I think is a better solution. In that case you are forced to check if it was what you really meant.
It's probably trying to help you avoid the dreaded typo:
if(a = b)
//logic error
Although I would expect an enviroment smart enough to warn you about that, to also be smart enough to have "oh, don't worry about that case" conditions.
Conditionals often include short circuit operators. So, given this example:
if ( a=func(x) && b=func(y) )
{
// do this
}
It may not be immediately obvious, but the second assignment would only occur if the first returned >0, and if func(y) had other side effects that you were expecting, they would not happen either.
In short, if you know what you are doing and understand the side effects, then there is nothing wrong with it. However, you must consider the possibility that someone else may be maintaining your code when you're gone and they might not be as experienced as you.
Also, future maintainers may think you intended the following:
if ( a==func(x) && b==func(y) ) ...
If they "fix" your code, they actually break it.
In languages that allways return a value on assignments it's not bad (I think it's quite common in functional languages), but (as others allready have said while I typed this) it should usually be avoided since you or someone else might mistake it for a comparison. The compiler should usually warn about it, but it can be ignored if you're sure what you're doing...
how would a code look like if you do not assign the $row value in the loop condition
this would be much more complicated i think...
although not that good to read for some maintainers, no?
well you can do it like
$next = mysql_fetch_assoc($result)
do{
...
...
...
$next = mysql_fetch_assoc($result) or break;
}while ($next)
I use them all the time, with loops (not sure why that would make a difference), like:
$counter = 0;
while( $getWhateverDataObj = mysql_fetch_object( $sqlResult )) {
$getWhateverObj->firstName[$counter] = $getWhateverDataObj->firstName;
$getWhateverObj->lastName[$counter] = $getWhateverDataObj->lastName;
$counter++;
}
And it works fine.

Categories