Using if/elseif without else

(Warning: PHP infant here!)

I’m playing with a simple set of conditions, such that I want to say

if (condition1) {do this}
elseif (condition2) {do this instead}
elseif (condition3) {do that instead}

Now, although this works nicely, I wonder if it’s considered bad coding not to end with an

else {whatever}

The if/elseif setup always seems to end with an else, but it seems you can’t have a condition on the else, yet each of my if statements carries a condition. If no conditions are met, I don’t want anything to happen.

I could end with

else {echo “”;} but that’s pointless.

I could also just have a series of if statements and forget elseif altogether.

Any thoughts on this? Is there a better way, or should I just stick with if/elseif (which is working, after all)? Sorry for such a nooby question!

An if statement by its self is absolutely fine.


$day = date('D');

if($day == 'Sun') {
   echo "We're closed today";
}

If you have a series of conditions where only one will be true it’s better to put the most likely first, then use else if on the subsequent ones so that PHP doesn’t have to keep evaluating each condition. It can stop once it finds the true one.

If you only need to test if one condition is true then there is no need for anything else.

Thanks cranial-bore, that makes sense.

I guess what I was wondering is what to do when there’s a possibility that none is true.

I’m experimenting with contact form validation, where potential error messages are placed under the form label depending on the mistake made. There are three possible mistakes, depending on the various conditions (field empty or invalid entry and/or too many characters). But of course, if no mistake is made I don’t want anything to happen at all.

Guess I’m after an else {no probs!}.

It’s up to you, but I prefer to put error messages into an array and show them all. For example, if an input has both a length requirement and a set of allowable characters, I feel it is better to show both rather than have someone make the input long enough and resubmit, only to get the invalid character message.

eg.

$error_messages = array();

if(empty) $error_messages[] = 'empty';
if(too short) $error_messages[] = 'too short';
if(too long) $error_messages[] = 'too long';
if(bad char) $error_messages[] = 'bad char';

foreach ($error_messages as $error_message) {

Yep, good point Allan. I was wondering if an array was the better solution. That’s what I started with, in fact, and the errors for all fields were just displayed as a list above the form. In breaking the messages up to appear with each label, this didn’t seem the best way. So I started with a simple error message that just stated all of the necessary rules for that field. I just thought it’s annoying to read a bunch of rules that don’t apply (such as a character limit that wasn’t breached anyway) so was trying to get fancy and just target the actual error made.

Perhaps I’ll make an array for any form field that has more than one condition to meet. With your example, you said you ‘prefer to show them all’, but I presume that by breaking errors into an array like you have you would only show the errors that actually occurred? Otherwise why not just show one error message that shows all conditions, based on one regex that requires all conditions be met?

I guess you could do an

if( !preg_match("/[-\\w]{4,10}/", $u_name) ) {
$error_messages['u_name'] = "Member names must be 4 to 10 characters long and can contain only letters, numbers, underscores and dashes";
}

if ($age < 21){
$error_messages['age'] = "Sorry , you're not old enough to see naked code";
}

Or maybe this would be better


$error_messages = "";
if(($u_name < 4) || ($u_name > 10) || (!preg_match("/[-\\w]+/", $u_name)) ) {
$error_messages .= "Member names must be 4 to 10 characters long and can contain only letters, numbers, underscores and dashes<br />";
}

if ($age < 21){
$error_messages .= "Sorry , you're not old enough to see naked code<br />";
}

Thanks Allan. In a way, that’s getting closer to what I have now. My original question was essentially about whether to use multiple if statements like that or to to use if/elseif. Obviously it’s not wrong to use multiple ifs, but I was wondering if there’s a more efficient approach to it. As cranial-bore said, the ideal is to avoid PHP having ‘to keep evaluating each condition’.

In some ways getting the logic right can be harder than writing the code.

There would be nothing wrong with an if-elseif-elseif without an ending else. eg.

$errors = NULL;
if(Major){
$errors = 'Major';
}
elseif(Minor){
$errors = 'Minor';
}
if($errors){

is perfectly acceptable.

Suppose you have a required field (called “name”) that must be 2-20 chars long, and can only contain alpha characters.
Ideally (as mentioned) you wouldn’t point out what the user already got right. The errors should tell them how
to fix what is wrong.

So possibly invalid situations are:
field not filled at all
field less than 2 chars long
field more than 20 chars long
field has invalid characters.

The logic might look a bit like this:


$errors = array();

//My field
if($value == '') {
	$errors['name'][] = 'Name is required';
}
else {
	$len = strlen($value);
	if($len < 2) {
		$errors['name'][] = 'Name must be at least 2 characters long';
	}
	else if($len > 20) {
		$errors['name'][] = "Name is too long ($len characters). 20 max";
	}
	
	if(!preg_match('/^[a-zA-Z]+$/', $value)) {
		$errors['name'][] = 'Name has invalid characters. Only alpha characters allowed';
	}
}

If the name field was completely blank the script doesn’t botter getting specific with lengths and regular expressions because the user hasn’t even tried. Once they put something in there, we’ll validate in more detail.
Then if the name is too short, we don’t bother testing to see if it’s also too long (impossible), but regardless of the length we’ll check for valid characters.
This means if the name is the wrong length AND has bad characters the user will find out in one go (not have to resubmit to find the next problem).

To display them you’d do something like this:


if(isset($errors['name'])) {
	echo implode("<br>\
", $errors['name']);
}

Disclaimer:
Markup aficionados won’t like the use of <br>. You can write a function to make an <ul> instead.
Real names may have hypens or accented characters. This isn’t robust, just a logic example.

Thanks Mittineague & cranial-bore, I think

if(){}elseif(){}if(){ }

is what I was looking for. Thanks for the example too, c-b. Nicely presented, and very clear. I’m learning PHP one grain of sand at a time, but it’s quite fun that way. Thankfully there’s no rush.

Consider this:
If

 if (cond) { stmt } 

is not considered bad coding,

 if (cond) { stmt} else {
   if (cond) {stmt} 
}

shouldnt be either. Now take the brackets off the else and shove the if back against the else…equivilant statements…

 if (cond) { stmt} elseif (cond) {stmt}

Good point, thanks StarLion. It’s funny that in all my web searching I never found an example of if / elseif that didn’t end with an else. I just thought if it were not mandatory to end with an else that I might have stumbled across an example. Certainly I’ve found that if/elseif/elseif works nicely.