1

I've got nested ternary operators in my code like this:

$error = $fault_all ? "ALL" : $fault_twothirds ? "TWOTHIRDS" : $fault_onethird ? "ONETHIRD" : "UNKNOWN";
        echo 'STATEERROR: ' . $error . ';';

They are listed in order of my preference left to right so if $fault_all and $fault_twothirds are true, I want "ALL" to be assigned to $error; The same if all of them are true. If all are false "UNKNOWN" should be assigned to error.

However, if any of them are true only "ONETHIRD" is returned, if all false "UNKNOWN" is returned. How do I make the "ALL" and "TWOTHIRDS" to be returned?

TomaszRykala
  • 927
  • 6
  • 16
  • 33

3 Answers3

2

I suggest you use ( and ) to separate the different ternaries from eachother, or use if/else clauses.

Nanne
  • 64,065
  • 16
  • 119
  • 163
  • Could be, although I'm not a fan of that. But that's just taste :) – Nanne Apr 16 '12 at 11:48
  • Fair enough, although switching booleans is very useful when you have whole bunch of operations that all return something that evaluates to `TRUE`, and you want to break the procedure and handle with an error when one of them fails, or vice versa. `case :` is a very useful/powerful construct when used correctly, although (much like `goto`) it should only be used by people who understand the implications of it... – DaveRandom Apr 16 '12 at 11:56
1

In terms of being able to debug and manage a list of states, I would recommend stopping usage of a ternary, which is unreadable, and use a switch, an if-elseif statement, or, if you anticipate a long list, an approach as follows:

<?php
function state( $states ) {
    foreach( $states as $state => $current ) {
        if( $current ) {
            return $state;
        }
    }
    return 'UNKNOWN';
}

$states = array(
    'ALL' => $fault_all,
    'TWOTHIRDS' => $fault_twothirds,
    'ONETHIRD' => $fault_onethird
);

var_dump( state( $states ) );

That said, this should work, I think:

<?php
$error = ( $fault_all ? "ALL" : ( $fault_twothirds ? "TWOTHIRDS" : ( $fault_onethird ? "ONETHIRD"  : "UNKNOWN" ) ) );
Berry Langerak
  • 18,561
  • 4
  • 45
  • 58
  • Thank you, and your nested ternaries do work indeed !! I tried using parentheses myself but I nested them incorrectly. – TomaszRykala Apr 16 '12 at 12:01
1

This is a known issue. -- veekun

Take for instance the following nested ternary ...

<?php 
$arg = 'T';
$vehicle = ( ( $arg == 'B' ) ? 'bus' :
           ( $arg == 'A' ) ? 'airplane' :
           ( $arg == 'T' ) ? 'train' :
           ( $arg == 'C' ) ? 'car' :
           ( $arg == 'H' ) ? 'horse' :
           'feet' );
echo $vehicle; 

prints 'horse'

As @berry-langerak stated use a control flow function ...

Using an object {array, structure} is much more reliable ... I.E.

$vehicle = (empty( $vehicle) ?

    array(

    'B' => 'Bus',
    'A' => 'Airplane',
    'T' => 'Train',
    'C' => 'Car',
    'H' => 'Horse',

    ):

    NULL
 );

 $arg = 'T';

 $vehicle = (! empty($arg) ? $vehicle[$arg] : "You have to define a vehicle type");

 echo($vehicle);
Edward J Beckett
  • 5,061
  • 1
  • 41
  • 41