14 Stimmen

ungewöhnliche ternäre Operation

Ich wurde gebeten, diesen Vorgang der ternären Operatorverwendung durchzuführen:

$test='one';

echo $test == 'one' ? 'one' :  $test == 'two' ? 'two' : 'three';

Der zwei ausgibt (überprüft mit php).

Ich bin mir immer noch nicht sicher, wie das funktionieren soll. Bitte, kann mir jemand die Logik dafür erklären.

15voto

Nicholas Wilson Punkte 9067

Nun, die ? und : haben den gleichen Vorrang, so dass PHP von links nach rechts parst und jedes Bit der Reihe nach auswertet:

echo ($test == 'one' ? 'one' :  $test == 'two') ? 'two' : 'three';

Erste $test == 'one' gibt true zurück, also haben die ersten Parens den Wert 'one'. Nun wird die zweite Ternäre wie folgt ausgewertet:

'one' /*returned by first ternary*/ ? 'two' : 'three'

eins" ist wahr (eine nicht leere Zeichenkette), also ist "zwei" das Endergebnis.

7voto

Grundsätzlich wertet der Interpreter diesen Ausdruck von links nach rechts aus, also:

echo $test == 'one' ? 'one' :  $test == 'two' ? 'two' : 'three';

wird interpretiert als

echo ($test == 'one' ? 'one' :  $test == 'two') ? 'two' : 'three';

Und der Ausdruck in Klammern ergibt wahr, da sowohl "eins" als auch "zwei" nicht null/o/andere Form von falsch sind. Wenn es also so aussehen würde:

echo $test == 'one' ? FALSE :  $test == 'two' ? 'two' : 'three';

Er würde drei drucken. Damit es funktioniert, sollten Sie die Kombination von ternären Operatoren vergessen und reguläre ifs/switch für kompliziertere Logik verwenden, oder zumindest die Klammern verwenden, damit der Interpreter Ihre Logik versteht und die Prüfung nicht auf die Standard-LTR-Art durchführt:

echo $test == 'one' ? 'one' :  ($test == 'two' ? 'two' : ($test == 'three' ? 'three' : 'four'));

//etc... It's not the most understandable code... 

//You better use:
if($test == 'one')
    echo 'one';
else { //or elseif()
...
}

//Or:
switch($test) {
    case 'one':
        echo 'one';
        break;
    case 'two':
        echo 'two';
        break;
//and so on...
}

5voto

Pekka Punkte 429407

Es funktioniert richtig, wenn Sie Klammern verwenden:

<?
 $test='one';
 echo $test == 'one' ? 'one' :  ($test == 'two' ? 'two' : 'three');

Ich verstehe es nicht zu 100 %, aber ohne Klammern muss die Anweisung für den Interpreter wie folgt aussehen:

echo ($test == 'one' ? 'one' :  $test == 'two') ? 'two' : 'three';

das Ergebnis der ersten Bedingung scheint als Ergebnis der gesamten ternären Operation zurückgegeben zu werden.

1voto

Felix Kling Punkte 751464

PHPS Dokumentation sagt:

Note : Es wird empfohlen, dass Sie ternäre Ausdrücke nicht "stapeln" . Das Verhalten von PHP bei der Verwendung von mehr als einem ternären Operator innerhalb einer einzigen Anweisung ist nicht offensichtlich:

Beispiel #3 Nicht offensichtliches ternäres Verhalten

<?php
// on first glance, the following appears to output 'true'
echo (true?'true':false?'t':'f');

// however, the actual output of the above is 't'
// this is because ternary expressions are evaluated from left to right

// the following is a more obvious version of the same code as above
echo ((true ? 'true' : false) ? 't' : 'f');

// here, you can see that the first expression is evaluated to 'true', which
// in turn evaluates to (bool)true, thus returning the true branch of the
// second ternary expression.
?>

Wenn Sie die falsche Anweisung in Klammern setzen, wird Folgendes gedruckt one :

echo $test == 'one' ? 'one' :  ($test == 'two' ? 'two' : 'three');

1voto

hamax Punkte 156

Ich denke, dass sie so bewertet wird:

echo ($test == 'one' ? 'one' :  $test == 'two') ? 'two' : 'three';

($test == 'eins' ? 'eins' : $test == 'zwei') ist ungleich null/null, also ist 'zwei' die logische Ausgabe

wenn Sie wollen, dass es richtig funktioniert, schreiben Sie:

echo $test == 'one' ? 'one' :  ($test == 'two' ? 'two' : 'three');

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X