This isn't something that can take a definite answer. Here's my take, it would be interesting to see what other opinions exist.
Scenario 1: Testing a boolean condition
This is the simplest case:
if (condition) {}
else {}
Specifying a condition as else if
would be redundant, and it's really obvious to the reader what the code does. There is no argument for using else if
in this case.
Scenario 2: Testing for a subset of infinite states
Here we are interested in testing for conditions A and B (and so on), and we may or may not be interested in what happens if none of them holds:
if (conditionA) {}
else if (conditionB) {}
else {} // this might be missing
The important point here is that there isn't a finite number of mutually-exclusive states, for example: conditionA
might be $num % 2 == 0
and conditionB
might be $num % 3 == 0
.
I think it's natural and desirable to use a reasonable amount of branches here; if the branches become too many this might be an indication that some judicious use of OO design would result in great maintainability improvements.
Scenario 3: Testing for a subset of finite states
This is the middle ground between the first two cases: the number of states is finite but more than two. Testing for the values of an enum-like type is the archetypal example:
if ($var == CONSTANT_FOO) {}
else if ($var == CONSTANT_BAR) {} // either this,
else {} // or this might be missing
In such cases using a switch
is probably better because it immediately communicates to the reader that the number of states is finite and gives a strong hint as to where a list of all possible states might be found (in this example, constants starting with CONSTANT_
). My personal criteria is the number of states I 'm testing against: if it's only one (no else if
) I 'll use an if
; otherwise, a switch
. In any case, I won't write an else if
in this scenario.
Adding else
as an empty catch-errors block
This is directly related to scenario #2 above. Unless the possible states are finite and known at compile time, you can't say that "in any other case" means that an error occurred. Seeing as in scenario #2 a switch
would feel more natural, I feel that using else
this way has a bad code smell.
Use a switch
with a default
branch instead. It will communicate your intent much more clearly:
switch($direction) {
case 'up': break;
case 'down': break;
default: // put error handling here if you want
}
This might be a bit more verbose, but it's clear to the reader how the code is expected to function. In my opinion, an empty else
block would look unnatural and puzzling here.