Tutorials

Sample uses for the Ternary Operator

Before we go bounding off with loads of examples I would like to quickly reiterate the 'things to remember' from the last page.

The ternary structure always runs with the order (conditional) ? : ;
Executed code within the true return clause does NOT end with a semi-colon ;
Each clause of the ternary can only contain one function call or method.

Most of the mistakes made while using ternary operators are caused by not adhering to the three useful notes above.

Basic Samples - One of the most basic ways of using the ternary is to echo out one of two phrases dependent upon a conditional test. The ternary operator can even be used inline with a little tweaking, allowing a smoother code flow. To enable an inline conditional echo, the entire ternary has to be encased within a set of parenthesis - such as the common 'alternating table row colours' scriptlet below.


$tmp_cnt
= 0;
while(
............)
    {
    echo
'<tr style="background-color:#'
        .((++
$tmp_cnt %2 == 0) ? 'AAA' : 'CCC' ).
    
'"><td>stuff</td></tr>';
    }


The tmp_cnt (temporary count) variable is pre-incremented within the ternary, then a modulus test determines the remainder after dividing by two. Upon a true return (even numbers) the string 'AAA' is echoed, while 'CCC' is echoed upon a false return (odd numbers).
As noted, the entire ternary (conditional and output clauses) is concatenated within the full echo string and enclosed within a holding parentesis pair, thus ensuring the ternary output is also echoed.

A very similar approach can be used for outputting a table where the input does not break a <tr> for every iteration. This approach would be used for things like outputting gallery images from a database call where you want perhaps four images per row (as per sample below).


$tmp_cnt = 0;
$per_row = 4;
while(
$row = mysql_fetch_array($result))
    {
    echo ((
$tmp_cnt %$per_row == 0) ? '<tr>' : '').
    
' <td><img src="images/' .$row['img_location']. '" /></td>'
        
.((++$tmp_cnt %$per_row == 0) ? '</tr>' : '');
    }
echo (
$tmp_cnt %$per_row !== 0)
    ?
'<td colspan="' .($per_row - ($tmp_cnt % $per_row)). '">&nbsp;</td></tr>'
    
: '';


Here we have used two inline ternary operators and one conditional echo. It might all look a tad confusing at the moment, so I will try to slowly explain what is happening at each instance.
We start by assigning a temporary variable and a variable for how many cells per row, then run straight into the while loop. I have used a common mysql query return here - one that returns a reference $row['img_location'] which is then echoed within every cell.
The start of the echo uses a modulus test to ascertain whether our $tmp_cnt divided by our $per_row leaves a remainder of zero (which would happen at $tmp_cnt = 0,4,8,12,16 etc). Because we start at zero, the first thing echoed is '<tr>' which is then followed by the default <td> with content.
The last part of the echo uses another ternary with a pre-increment of the $tmp_cnt value - so on the first iteration the modulus test compares to one (as the $tmp_cnt is pre-incremented before testing) and thus fails. The output of the ternary indicates that for a fail/false return we echo nothing - it will only echo a closing </tr> tag when pre-adding one to our $tmp_cnt is exactly divisible by 4 (or whatever $per_row is set to).
The while loop is now closed. If we start another iteration of the while loop immediately after our ternary has echoed a closing </tr> we obviously output a starting <tr> as $tmp_cnt is still the same.

If we simply closed off the current </tr> at this point there is a high likelihood that our code wouldn't validate, we would probably have a row of cells that were not completed. For example, with 7 iterations of the while loop, we would have 4 cells in the first row, 3 cells in the second row and no closing </tr> tag.
The final conditional (written as a ternary, to keep in practice) deduces whether we have just echoed a closing </tr> tag by again testing $tmp_cnt against $per_row. If we haven't just echoed out a closing tag, a simple bit of math builds an empty <td> cell with associated colspan and finishes with our needed </tr>.

You may also notice that for the last line I split the ternary over three lines, hopefully making it a touch more readable.

So far we have only used a single ternary at once, which though useful is only part of its potential. Multiple ternary operators can be built together into code blocks with all the function of multiple if-else clauses, only with half the byte-size. The next (and final) section of this tutorial deals with stacked ternary calls and shows some sample usage.

Back to Using the Ternary Operator
Advanced and Multiple Ternary usage

SiteMap