DEV Community

Cover image for Simple PHP Control Structure Refactoring
George Hanson
George Hanson

Posted on • Originally published at georgehanson.co.uk

Simple PHP Control Structure Refactoring

This article was originally posted on my blog - Simple PHP Control Structure Refactoring

Before we get into it, I posted all three of these little refactors on my Instagram and Twitter pages. Be sure to check those out as there is a handy little image you can save.

One common thing I see when looking at code is some simple refactors that can make it slightly more readable. One of these "code smells" are if control structures. There are some occasions where these can be made much simpler and even reduced to just one line.

In this article I'll go through three simple refactoring tips to help tidy up your code. I hope you find them useful so let's begin.

Ternary Operator

The ternary operator is a simple but powerful operator that I find myself using throughout my code-base. This operator allows us to easily check a condition and return a value in just one line.

Let's take a look at an example. Here we are looking at a five line control structure. We are checking if the user is logged in or not and changing the value of the welcome variable accordingly.

if ($user->isLoggedIn()) {
  $welcome = 'Welcome '.$user->firstName;
} else {
  $welcome = 'Welcome Guest';
}

Simple enough right?

Well we can make it even simpler using the Ternary operator. Here is an example of how we could refactor this control structure.

$welcome = 'Welcome '.($user->isLoggedIn() ? $user->firstName : 'Guest');

And there we go. We have refactored the control structure into just one line. But how does this work? Let's break it down. The first thing we are doing is concatenating the result of the conditional to the string Welcome. With me so far?

Great. So let's take a look at the conditional itself. We are checking if the user is currently logged in, if they are it returns the value after the ? which in this case is the users first name. If not it returns the value after the : which is "Guest".

As you can see this is a really simple, yet powerful shortcut to clean up control structures.

'Elvis' Operator

Ok, ok. This isn't actually called the Elvis operator, but it does look like a little guy with Elvis' hair style - so it has been dubbed as such.

This instead is actually the Ternary operator, but a short-hand version of it. There are some cases where we want to return the value of what we are evaluating rather than a separate value. In which case we can use the Elvis operator.

Sounds a little confusing? Don't worry, let's take a look at an example and it will all become clear.

Here we want to get the url for the avatar that should be displayed. If the user has an avatar url we will use that, otherwise we want to use the default.

if ($user->avatarUrl) {
  $url = $user->avatarUrl;
} else {
  $url = '/default.jpg';
}

Take a look at how we can make it simpler. Here is an example of how we could refactor this control structure.

$url = $user->avatarUrl ?: '/default.jpg';

Can you see why it has been dubbed the Elvis operator?

You can see that this is very similar to using the long-form Ternary operator. But it is slightly different. If the avatarUrl is truthy it will return that value, otherwise it will return the string. This is the same as writing the following:

$url = $user->avatarUrl ? $user->avatarUrl : '/default.jpg'; 

Null Coalescing Operator

This is the final operator I'm going to talk about. This operator strictly checks if the left operand is not null or if it exists as a variable, array index or object property. This is another awesome little feature that was added in PHP 7.

This operator acts similarly to the PHPs isset function as well as the 'Elvis' operator.

The most common use case I find for these is checking if an item exists in an array and if it does setting that value to a variable, otherwise setting it to a default. That way we avoid errors where the index does not exist.

Let's take a look at an example.

Here I am checking the data in a POST request to see if the user has provided a slug for the post. If one has been provided we will set the slug variable to that value, otherwise I want to call a generateSlug function.

$slug = isset($_POST['slug']) ? $_POST['slug'] : generateSlug();

As you can see we are already using the Ternary operator but we can make this even simpler by using the Null Coalescing operator.

To use this operator we simply use ?? with the default value as the right operand. Here is how we can refactor the code above to make it easier to read.

$slug = $_POST['slug'] ?? generateSlug();

Much nicer, using the Null Coalescing operator we have simplified it massively. It checks if the $_POST['slug'] value exists and if it does, assigns it to the slug variable. Otherwise we call the function.

I hope that you found this post useful. I know that I use all three of these techniques throughout my code-base to clean it up and I hope you do to. Be sure to check out my Twitter and Instagram pages for handy little images you can save.

Top comments (4)

Collapse
 
tarialfaro profile image
Tari R. Alfaro

Do take note, that a lot of PHP developers may not be aware of this. Generally in the real-world, it's best practice to stick with:

if ( $condition ) {
    # . . .
} else {
    # . . .
}

Because every programmer should understand that. And it's actually pretty readable despite requiring a few more lines of code compared to the ternary operator. (I didn't know about the null coalescing or 'Elvis' operator)

Otherwise, if it's a personal project, and you're not expecting others to read it, by all means go with these operators.

But thank you. I learned a couple new things today.

Collapse
 
poldiwa profile image
Paul John Diwa

also an alternative, based on the given example.

$url = '/default.jpg';

if ($user->avatarUrl) {
  $url = $user->avatarUrl;
}
Collapse
 
georgehanson profile image
George Hanson

Hey :)

Sure, it is generally in the real-world better to use full if control structures. It comes down preference, the complexity and readability based on a case-by-case.

I just used these as examples to demonstrate the operators, but in the real-world if you are doing quite a few of these repetitive simple structures then it is sometimes better to reach for a ternary operator. It just comes to the circumstance at the time and it is up to the developer to decide whether or not it is worth reaching for it.

But I'm glad you learned something new.

Collapse
 
tarialfaro profile image
Tari R. Alfaro • Edited

I think it would have a great use case if you're building a lot of options in a function or class method.

so instead of this:

$key = 'default value';

if (\array_key_exists('key', $options)) {
    $key = $options['key'];
}

# But a bunch more ...

But instead we could do a bunch of these:

$key = $options['key'] ?? 'default value';

Also, I'd like to say sorry. I don't think we should always be doing the regular if then else statement. As you said, it's case-by-case. Developers should just learn the language instead.

I think everyone should understand how the ternary operators work. Their symbols are similar to that of && or ||.

Must've missed it, because I didn't see any examples of the 'Evlis' operators or null coalescing.

Anyways, thank you for the great article. w^