[PHP]Pyramid If...Else vs. Else If

Joined
Aug 6, 2009
Messages
2,146
Reaction score
438
My friend says that pyramid If...Else is worse and might make script go nuts. On other side Else If is better, he says.

Example of Pyramid If...Else
PHP:
if ( mssql_num_rows( $checkUsername ) > 0 )
			{
				showMessage( "error", "Such username is taken.", 3, "index.php?module=signup" );
			}
			else
			{
				if ( strlen( $username ) < 6 || strlen( $username ) > 12 )
				{
					showMessage( "error", "Username lenght must be between 6 and 12 characters long.", 3, "index.php?module=signup" );
				}
				else
				{
					if ( strlen( $password ) < 6 || strlen( $password ) > 12 )
					{
						showMessage( "error", "Password lenght must be between 6 and 12 characters long.", 3, "index.php?module=signup" );
					}
					else
					{
						if ( !isValidEmail( $email ) )
						{
							showMessage( "error", "Please enter valid email address.", 3, "index.php?module=signup" );
						}
						else
						{
							if ( $gender != 0 || $gender != 1 )
							{
								showMessage( "error", "Dear hacker, your gender must be 0 or 1.", 3, "index.php?module=signup" );
							}
							else
							{
								if ( strlen( $question ) < 10 )
								{
									showMessage( "error", "Question must be at least 10 characters long.", 3, "index.php?module=signup" );
								}
								else
								{
									if ( strlen( $answer ) < 3 )
									{
										showMessage( "error", "Answer must be at least 3 characters long.", 3, "index.php?module=signup" );
									}
									else
									{
										if ( strlen( $name ) < 3 )
										{
											showMessage( "error", "Your name must be at least 3 characters long.", 3, "index.php?module=signup" );
										}
										else
										{
											if ( strlen( $zipcode ) != 5 )
											{
												showMessage( "error", "Zip code must be 5 numbers long.", 3, "index.php?module=signup" );
											}
											else
											{
												$t_id_idx = 0; $t_propid = 0;
												$result = mssql_query( "SELECT id_idx, propid FROM lunamember..chr_log_info" );
												while($row = mssql_fetch_array($result)){
													if($row['id_idx'] > $t_id_idx){
														$t_id_idx = $row['id_idx'];
													}
													if($row['propid'] > $t_propid){
														$t_propid = $row['propid'];
													}
												}
												$t_id_idx++;
												$t_propid++;
												$insertUser = mssql_query( "INSERT INTO lunamember..chr_log_info (id_idx, propid, id_loginid, id_passwd, id_sexType) VALUES ('$t_id_idx', '$t_propid', '$username', '$password', '$gender');" );
												
												if ( $insertUser )
												{
													$insertUserPlus = mssql_query( "INSERT INTO lunamember..chr_log_info_plus (id_idx, id_loginid, id_pw_Q, id_pw_A, id_name, id_zipcode, id_email) VALUES ('$t_id_idx', '$username', '$question', '$answer', '$name', '$zipcode', '$email');" );
													showMessage( "success", "Account has been created. Enjoy Athens Luna Online", 3, "index.php?module=news" );
													$_SESSION['user_idx'] = $t_id_idx;
													$_SESSION['logged_in'] = true;
													if ( $insertUserPlus )
													{
														showMessage( "success", "Additional info has been inserted as well." );
													}
													else
													{
														showMessage( "success", "There was a problem with inserting additional information. You can change/add your additional information in game panel." );
													}
												}
												else
												{
													showMessage( "error", "Weird error occured. Tell admin that he has problem in registration script." );
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}

Example of Else If:
PHP:
if ( $crap == true )
{
	echo "Crap is true";
}
else if ( $pee == ture )
{
	echo "Pee is true";
}
else
{
	echo "Neither crap or pee is true";
}

Is my friend stupid and says crap or I have been doing if...else in worst way all time?
 
You know that both are totally the same, right? Besides, this is stupid generally, go for something like

PHP:
$err = array();

if (strlen( $username ) < 6 || strlen( $username ) > 12) {
   $err['lenght'] = "Username lenght must be between 6 and 12 characters long";
}

if (!isValidEmail( $email )) {
   $err['validMail'] = "Please enter valid email address.";
}

if (empty($err)) {
   //proceed
} else {
   //this or anything else you like
   foreach ($err as $error) {
      echo $error;
   }
}


Or use switch if you insist on doing it if/else like.
 
Last edited:
offtopic:
is english your second language because i can tell with this sentence "...in worst way all time?"

ontopic:
else if looks better and is easier to edit if encounter a error somewhere inside the script. unless you dont mind the wall of } everywhere.

i think it doesnt matter if you do it the way you did it or if you did it like your friend said. its your script, not his. if he wants you to do it a different way, have him code it.
 
There will be a time style matters to you, so why not do it well already? The pyramid version just looks horrible and avoids using else if for no reason.

Performance-wise, it's hard to think of a situation where they wouldn't be exactly the same, except your pyramid version has more characters to read, so it's slower (by a ridiculous margin, but still).
 
You use the one that'll best suits your needs.

PHP:
if (a == b)
{
  var = 1;
}
else if (a == c)
{
  var = 2;
}
else if (a == d)
{
  var = 3;
}

PHP:
if (a == b)
{
//dostuff
}
else
{
//dootherstuff
  if (b == 1)
  {
  }
  else if (b == 2)
  {
  }
}

in example 1 you are checking one thing over and over while in example 2 you're checking one item and then having another if/else should it be false. Turning example2 into an "else if" would not work the same if you had other code outside the second "if".
 
Why? If a conditional statement returns false, the entire code block is disregarded. Your code can be a staggering 25+ blocks deep, if it's false, it'll be ignored. If true, it'll be executed.

Write you code so you and others can read it. If you try to make all your code just 1/2 levels deep, that makes it impossible to have a function containing a loop, containing a conditional statement, which is very common, and there's nothing wrong with you or your code if you need to do this.

Opinions always differ, everyone reads and writes code differently, to a point. Try your best to follow standards and common techniques, but when it comes down to it, whichever way you feel most efficient going back to find & fix mistakes is the best way.

Like foxx said, it's all the same. Like bone-you said, different situations might spark different techniques for the best efficiency. Conditional statements are so simple, it doesn't matter too much to stack them.

What your friend said could be pretty valid, if you don't understand programming too well. For example, if you have a conditional statement with a function inside it, that's not exactly good practice, but in many languages it works. If for whatever reason, two separate conditional statements create the same function, then the program will (in most languages) throw an error, or "go nuts" about the duplicate function. Even variables, you know, if you don't declare/use the variable right, the program will "go nuts". Having a bunch of code blocks isn't really bad unless you do use bad practice.. For instance, a function inside a loop is just stupid, but a loop inside a function could make perfect sense.

If you can, it's more user-friendly to stack the little conditional statements so you can build errors, like so:
PHP:
var err = null;
if(name.length < 1)
{
    err+="Please enter a user-name.";
}
if(pass.length < 1)
{
    err+="Please enter your password.";
}

if(err.length<1)
{
    run_query(name,pass);
}
return err;

However, it's more efficient to return quicker, like so:
PHP:
var err = null;
if(name.length>0)
{
    if(pass.length>0)
    {
        run_query(name,pass);
    }
    else err+="Please enter a password.";
} else err+="Please enter a user-name.";
return err;

So, it all depends on what you're working on to decide which methods you use. Just use your best sense to make sure your program never contradicts itself.
 
Last edited:
Why? If a conditional statement returns false, the entire code block is disregarded. Your code can be a staggering 25+ blocks deep, if it's false, it'll be ignored. If true, it'll be executed.

It's still interpreted in interpreted languages. Further, to make it into the inner loops, many comparisons must be made, that even in compiled languages requires branching conditionals which make it more difficult to properly prefetch etc. Simply, it kills performance in most cases.

If you need to check 50 conditionals at the same time, there are easier and more efficient ways to do it. Doing if(...)else{if(...)else{if(.........} is just stupid.

Write you code so you and others can read it. If you try to make all your code just 1/2 levels deep, that makes it impossible to have a function containing a loop, containing a conditional statement, which is very common, and there's nothing wrong with you or your code if you need to do this.

I said more than 3 levels deep. A function doesn't count as nesting unless you're working with closures in languages that support them. Debugging a massively huge function with multiple conditionals running for loops that do lots of conditional testing that get out to 5-6 nests and is 100+ lines long is actually a much bigger pain in the ass than being smart and making a state machine or something that can far more efficiently and concisely do the same thing.

Opinions always differ, everyone reads and writes code differently, to a point. Try your best to follow standards and common techniques, but when it comes down to it, whichever way you feel most efficient going back to find & fix mistakes is the best way.

"Feeling" more efficient doesn't make something even decent code. Just because you can code something that way with almost 0 programming knowledge doesn't mean you should. If Linus did that with linux, everyone would laugh at the project that requires a damn beowulf cluster just to boot, just to have it crash in 20 seconds due to an undebuggable bug.

Like foxx said, it's all the same. Like bone-you said, different situations might spark different techniques for the best efficiency. Conditional statements are so simple, it doesn't matter too much to stack them.

Sure it does. Branches should be minimized because they totally **** up what your processor does that makes it fast. [ame]http://en.wikipedia.org/wiki/Branch_predictor[/ame].

What your friend said could be pretty valid, if you don't understand programming too well. For example, if you have a conditional statement with a function inside it, that's not exactly good practice, but in many languages it works. If for whatever reason, two seperate conditional statements call the same function, then the program will (in most languages) throw an error, or "go nuts" about the duplicate function. Even variables, you know, if you don't do it right, the program will "go nuts". Having a bunch of code blocks isn't really bad unless you do use bad practice.. For instance, a function inside a loop is just stupid, but a loop inside a function could make perfect sense.

Functions inside loops can be more powerful than you know. Closures are incredible. Learn LISP.

If you can, it's more user-friendly to stack the little conditional statements so you can build errors, like so

Users don't read your code. It doesn't matter how output is generated. And a "Your username and/or password are invalid" is more than descriptive enough for even the dumbest user:

PHP:
function test(name,pass){
  if(!name.length || !pass.length) return "Your username and/or   password are invalid.";
  return null;
}

Further, in your code you access a property in a null. That behaviour is undefined, most engines will throw a runtime error.
 
Looks like you're having fun.

Hmm, didn't know that about my processor, I'll have to look into that. I'm still not convinced you're completely right, to be honest. I also don't see how/why/what language you'd need to create a function multiple times in a loop.. I mean, it doesn't compute to me, not saying you're pulling it all out of a hat or anything..

Also, you're misunderstanding me in like 80% of your arguments. In context, that one time I said "efficiency", actually meant how efficient he is at interpreting his own code- developer friendliness.. Off topic, Did I insult you by any chance? I didn't mean to, I was just taught differently about conditional statements.. Maybe in this particular case, language actually DOES matter.

I'm pretty certain that the PHP interpreter doesn't read the false conditional statements any more then the condition itself to find out it's false. So if it's false, then the 10-level conditional statements don't get read. When they return true, the question is: how much does the interpreter spend on a conditional statement, and does it spend more/less/equal time on stacked, than inherited?

Notice what Daevius says in this thread:
http://forum.ragezone.com/f86/php-tutorial-elseif-513239/

That's partially why I don't think it matters one way or the other in terms of efficiency. If it does, then I apologize, but inheriting if/else statements for readability reasons is no less efficient than stacking a bunch of if/elseif statements. It may be slightly more efficient, but not noticeably. At least as PHP is concerned.
 
Last edited:
Looks like you're having fun.

Hmm, didn't know that about my processor, I'll have to look into that. I'm still not convinced you're completely right, to be honest. I also don't see how/why/what language you'd need to create a function multiple times in a loop.. I mean, it doesn't compute to me, not saying you're pulling it all out of a hat or anything..

Also, you're misunderstanding me in like 80% of your arguments. In context, that one time I said "efficiency", actually meant how efficient he is at interpreting his own code- developer friendliness.. Off topic, Did I insult you by any chance? I didn't mean to, I was just taught differently about conditional statements.. Maybe in this particular case, language actually DOES matter.

I'm pretty certain that the PHP interpreter doesn't read the false conditional statements any more then the condition itself to find out it's false. So if it's false, then the 10-level conditional statements don't get read. When they return true, the question is: how much does the interpreter spend on a conditional statement, and does it spend more/less/equal time on stacked, than inherited?

Notice what Daevius says in this thread:
http://forum.ragezone.com/f86/php-tutorial-elseif-513239/

That's partially why I don't think it matters one way or the other in terms of efficiency. If it does, then I apologize, but inheriting if/else statements for readability reasons is no less efficient than stacking a bunch of if/elseif statements. It may be slightly more efficient, but not noticeably. At least as PHP is concerned.

Off Topic:
Hey, the way I used null was to declare a string with no contents, no errors in JS/AS

I hardly find what the OP posted readable, editable, or debuggable. Scrolling right in a text editor adds a second dimension to programming which should not be there. If you can't mentally process while thinking about the problem that number of nests, it's better to find a more succinct way of approaching the problem. Humans can't handle mentally more than a few scopes without extensive backtracking and killing thought performance, and when programming it's all about figuring the problem out in your head then putting that into terms to do what you want in whatever language it happens to be, and if/then/else's nested that deep like that are a terrible way to implement a single scope conditional that one can mentally conceive of but can't explain. To someone reading that code later, the conditional is not so clear an image in the mind and so reading 7 nests to figure out what it is requires a lot of extra time than something smaller with a small comment would have.

In developing when you have a set of conditionals which must all be met simultaneously, lest even one be missing an error message exists, you can devise a way to represent the needed conditional requirements in an array and use a function which tests each element in the array, returning either null for success or an error string on error (on the first error it encounters). I do this with parameter collecting from $_GET and $_POST in my scripts. Logically we see we want all of these SIMULTANEOUSLY to be true, otherwise we'd like to format a message based on the first one we find that's not true, that mentally takes the place of a single if(...), where the error is magically tailored to the first short circuit of a long (a && b && c && d && ...) in the conditional. You can actually do this with closures, in any ugly way, or with variable length argument lists in various languages, or other methods in languages like LISP. So in closing, programming is the art of taking a mental thought process of doing SOMETHING we find useful for some reason and representing the thought we have of that system working as a program in an efficient manner. It shows inexperience or poor skill if it requires a considerably monstrous construct to represent what is such obvious logic to a person.

Also, in JS, I tested that exact code and it produces errors, for the reason I said: err is null. Also, a string with no content is either new String(); or ""/''. The prior is a string object (which has a .length property of 0), the latter is a native string, and when you try a .length on it, the engine will automatically construct a new String object in its place, so:

PHP:
var x = "";
document.print("length: " + x.length);

Is the same as adding an intermediate step with an invisible variable:

PHP:
var x = "";
var %x = new String(x);
document.print("length: " %x.length);

(% used because it's illegal in variable names to represent invisibility)
 
Okay, well anyway.

In conclusion of everything:
Too much nesting is ugly, not enough nesting is ugly.. To the OP, make it developer friendly, as in, try to shorten the if/else statements so they're easy to read. Somewhere between 3-6 "tabs" should be where you try to draw the line. As in, decide on your own how much nesting is too much.

Reading these replies, I'm sure you'll find a good solution for your script. Your friend wasn't exactly 100% right, but the instinct alone that you really shouldn't nest them that far in, is good of your friend.

It doesn't exactly make the program "go nuts", but it is hard to go back and develop when a horizontal scroll-bar is involved. (or worse, the word wrap, eek!)

Best of Luck,
- Spence
 
Back