2013-01-08 6 views
13

Dlaczego to drukowanie 2?Serwer trójskładnikowy PHP nie działa zgodnie z oczekiwaniami

echo true ? 1 : true ? 2 : 3; 

z moim rozumieniem, należy wydrukować 1.

Dlaczego nie jest to działa zgodnie z oczekiwaniami?

+3

Nigdy kiedykolwiek dobry powód, aby gniazdo operatorów trójskładnikowych ... i instrukcja wyraźnie ostrzega o tym –

+1

http://php.net/manual/en/ language.operators.comparison.php - 'Uwaga: Zaleca się unikanie" układania "potrójnych wyrażeń. Zachowanie PHP przy użyciu więcej niż jednego operatora trójskładnikowego w ramach pojedynczej instrukcji jest nieoczywiste "- wyrażenia trójskładnikowe pozostają asocjatywne. – DaveRandom

+1

jeśli * musisz * zagnieździć trójdzielną operację, a następnie użyj nawiasów wokół nich. W rzeczywistości, polecam używanie nawiasów klamrowych dookoła potrójnych; dzięki temu są bardziej czytelne, nawet jeśli ich nie zagnieżdżasz. – SDC

Odpowiedz

23

Bo co napisałeś jest taka sama jak:

echo (true ? 1 : true) ? 2 : 3; 

a jak wiadomo 1 oceniana jest na true.

Czego spodziewać się:

echo (true) ? 1 : (true ? 2 : 3); 

Więc zawsze używać nawiasów, aby uniknąć takich nieporozumień.

Jak już napisano, wyrażenia potrójne pozostają asocjatywne w PHP. Oznacza to, że na początku zostanie wykonany pierwszy od po lewej, następnie drugi i tak dalej.

3

W razie wątpliwości używaj nawiasów.

Operator trójskładnikowy w języku PHP jest lewostronny w przeciwieństwie do innych języków i nie działa zgodnie z oczekiwaniami.

3

Oddzielna druga klauzula potrójna z nawiasami.

echo true ? 1 : (true ? 2 : 3); 
2

z docs

Example #3 Non-obvious Ternary Behaviour 
<?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. 
?>