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?
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" ) ) );
I suggest you use (
and )
to separate the different ternaries from eachother, or use if/else clauses.
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);