Code Clarity Tip

Using PHP’s switch statement to clarify your code.

By Bob Ray  |  December 19, 2023  |  3 min read
Code Clarity Tip

This is a quick tip on making your PHP code easier to read (both for others, and for you). Complicated if statements can be fairly obscure, so we’ll look at an alternative that I think is a little easier to read.

The Problem

Consider this line of code that tests a user’s primary user group:

if ($userGroup == 'EditorUsers' || $userGroup == 'AdminUsers' || $userGroup == 'ContentEditors' || $userGroup == 'SubAdminUsers' || $userGroup == 'Publishers') {
    /* Do something */
} else {
    /* Do something else */
}

The code above is difficult to read, especially if you’re not that used to reading PHP code, though it could be improved some by reformatting it. It’s also easy to make a fatal typing error (like using = instead of == or | instead of ||) when entering or modifying complex if statements like the one above.

An Alternative

Here’s another way to do the same thing using PHP’s switch statement:

switch($userGroup) {
    case 'EditorUsers':
    case 'adminUsers':
    case 'ContentEditors':
    case 'SubAdminUsers':
    case 'Publishers':
        /* Do something */
        break;
    default:
       /* Do something else */
      break;
}

I think the second version is a little easier to understand and much easier to modify without making a mistake. Of course, this technique only works if the variable being tested is the same for each condition, you use “OR” for each test, and you are always testing it for equality.

Another Example

Here’s a better example involving multiple if and elseif statements:

if ($userGroup == 'EditorUsers' || $userGroup == 'AdminUsers') {
   /* Action 1 */
} elseif ($userGroup == 'ContentEditors' || $userGroup == 'SubAdminUsers') {
   /* Action 2 */
} elseif ($userGroup == 'Publishers') {
  /* Action 3 */
} else {
  /* Action 4 */
}

Here’s the “switch” version:

switch($userGroup) {
    case 'EditorUsers':
    case 'AdminUsers':
        /* Action 1 */
        break;

    case 'ContentEditors':
    case 'SubAdminUsers':
        /* Action 2 */
        break;

    case 'Publishers':
        /* Action 3 */
        break;

    default:
        /* Action 4 */
        break;
}

Again, I think the switch version is much easier to follow. Usually, we end each case of the switch statement (or group of cases) with break;. Otherwise, the execution will “fall through” to the next case and its code will execute too. What we have above, where we list a number of cases, then one break statement, is called an “intentional fallthrough”. It works in this case because all the cases are mutually exclusive. In other words, of all the case statements in the entire script above, there can be only one (or none) that matches the search term.

Performance

If you’ve been reading my Blog articles, you know that I’m a big fan of faster code. I benchmarked the two methods in the first example with 1,000 iterations for each one. The difference in speed depends somewhat on the value of the $userGroup variable and the position of that variable in the list. In my tests, the if statement was slightly faster in most cases, but the largest difference I was able to produce was less than one ten-thousandth of a second. Remember—that’s for 1,000 iterations. That means (if my math is correct) that in a single pass, the speed difference is less than one ten-millionth of a second! That’s a performance hit I can live with.

Wrapping Up

Admittedly, the technique described here won’t work for all situations, but it’s a nice option to have on hand for those cases where it does work.


Bob Ray is the author of the MODX: The Official Guide and dozens of MODX Extras including QuickEmail, NewsPublisher, SiteCheck, GoRevo, Personalize, EZfaq, MyComponent and many more. His website is Bob’s Guides. It not only includes a plethora of MODX tutorials but there are some really great bread recipes there, as well.