ternary

A Shorter Ternary Operator in PHP 5.3

The ternary operator is simply awesome. It allows for some really beautiful if-else style variable assignments:

$can_drink = ( $age <= 21 ) 
  ? true 
  : false ;

This operator let’s you evaluate a condition, and return one of two results based on that condition. In the example above we’re testing the legal drinking age. If the age is greater than or equal to 21, the value of $can_drink will become true (the first value after the question mark). Otherwise, the value of $can_drink will become false (the value after the colon) (this particular example doesn’t require a ternary operator as the condition evaluated will itself result in either true or false). You can test multiple conditions within the main ternary condition, but the rules still stay the same – if the main condition evaluates to true, the first result is returned, otherwise, the second result will be returned.

The operator is nice, don’t get me wrong, but it’s not always fun to play with. Suppose you’re searching for a value within an array and you would like to return it if found:

$job_title = array_search( "Jonathan Sampson", $emp )
  ? array_search( "Jonathan Sampson", $emp )
  : "n/a" ;

You’ll note that my white-spacing is a little different, but this won’t effect the results of the operator. What I’m doing here is checking to see if “Jonathan Sampson” is a value within the employees array. If “Jonathan Sampson” is in the array, I’d like to return the key for that entry, so I replicate the condition (which returns the key) in the first slot after the question mark so it will be returned if the condition is true. Otherwise, if “Jonathan Sampson” isn’t found in the array (and the condition returns false) I return the string “n/a”.

Either the $job_title variable will have a value like “Software Developer” (given the key for “Jonathan Sampson” is “Software Developer”) or it will be “n/a”. The problem here is that we’re performing the array search twice, which is really ugly. There’s another way we could do this:

$job_key = array_search( "Jonathan Sampson", $emp );
$job_title = $job_key ? $job_key : "n/a" ;

Now we’re only performing the array search once. The array_search function returns either the first key found, or FALSE. As such, $job_title will contain either the key, or the string. But this is still a bit ugly. We’ve got two lines, and repeated calls to the $job_key array.

In PHP5.3 we’re given the option of a much shorter ternary, eliminating the middle column completely. This is helpful when using functions like array_search() which themselves return the result we actually want. They serve both as the condition (since they will return FALSE when the value isn’t found) and the result (since they return the key if the value is found). Now we can do something like this:

$job_title = array_search( "Jonathan Sampson", $emp )  ?: "n/a" ;

Now, if array_search() finds the key, it’s automatically returned into the $job_title variable, else, “n/a” will be returned. Elegant.

6 thoughts on “A Shorter Ternary Operator in PHP 5.3

  1. Nate

    I’ve been googling to see if anyone’s found a decent use for the ternary in php 5.3 with the missing argument. Yours is the closest I’ve seen to a decent use, but it’s still a little dangerous. array_search in this mode will only work if the array indexes are strings, none of which are “empty” (’0′, ”, etc).

    If your $emp array is numerically indexed [ie: $emp = array('Joe', 'John');], then the search will fail to find Joe with this method, as array_search will return 0 which is not truth-y, and will fall back to ‘n/a’.

    My search for a sensible use of short-hand ternary continues…

    1. Jonathan Sampson Post author

      Hello, Nate.

      A good use would be to use it to provide a default value in the place of a missing or falsy value. In JavaScript, for instance, people currently use the || operator to do this. This is an abusage, and as such JavaScript may soon adopt the same syntax PHP uses.

      $name = "" ;
      echo $name ?: "Nobody" ;

      Here, the output would be “Nobody”, since $name is falsy. You could use this for assignment as well if you wanted. But the important there here, as you pointed out, is the concern for falsy values.

      I apologize for the example in the blog post above – it’s not really a great example for how this operator should be used.

  2. Nate

    Javascript will never abandon ||, especially for an ugly hack like a short-hand ternary. PHP is the one that just introduced yet another ugly feature into the language.

  3. NIck

    Thanks for this blog post, I wasn’t aware of the new even shorter ternary.

    In my case I am calling one of my own functions that runs a query on a database returning either the id of the matching record or false.

    In one instane I need to set a default value if I get a false, so the new ternary allows me to do it without either an extra database access, or having to use 2 lines of code.

    Instead it’s nice and neat:

    $iType = $this->getTypeId($sType) ?: $iDefault;

Comments are closed.