2011-01-26 16 views
5

PHP üçlü operatörünü kullanmakta oldukça yetenekliyim. Ancak aşağıdaki kodun if-else eşdeğer yapısıyla niçin uyuşmadığını anlamaya çalışırken bir barikata çarptım. Test farklı sayılarda üç kez çalıştırıldı. Her yapının çıkışı kodun altında.iç içe geçmiş php üçlü sıkıntı: ternary output! = If - else

Üçlü:

$decimal_places = ($max <= 1) ? 2 : ($max > 3) ? 0 : 1; 

Üçlü Çıktı:

max: -100.000 ondalık: 0

max: 0,48 ondalık: 0

max: 0.15 ondalık: 0

If-Else

if($max <= 1) 
$decimal_places = 2; 
elseif($max > 3) 
$decimal_places = 0; 
else 
$decimal_places = 1; 

If-Else Çıkışı:

max: -100.000 ondalık: 2

max: 0,48 ondalık: 2

max: 0.15 ondalık: 2

Lütfen bu iki kontrolün neden olduğunu söyler misiniz? Yapılar aynı verileri vermiyor mu?

+4

Üçlü operatörlerin yuvalanmasının iyi bir fikir olmamasının bir nedeni –

+1

Tam olarak eşdeğer değiller. Tüm diğer şey, üçlü yapıya kısa devre yapacak. Ayrıca iç içe olmaları gerekmiyor. –

+1

[PHP Üçlü Operatörler El Kitabı] 'dan (http://de3.php.net/manual/en/language.operators.comparison.php#language.operators.comparison.ternary): "İstiflemeden" kaçınmanız önerilir. "Üçlü ifadeler. PHP'nin tek bir deyim içinde birden fazla üçlü operatör kullanırken davranışı açık değildir. – Gordon

cevap

18

Sağ tarafta gösterilen üçlü ifadesi tek bir ifade olarak kendisi tarafından değerlendirilecek olacak böylece parantez sarılı gerekiyor: Yeri istediğiniz sıra kodlu olduğundan emin olmak için parantez

Bu olursa-else çevrilmiş,

$decimal_places = (($max <= 1) ? 2 : ($max > 3)) ? 0 : 1; 

// Another way of looking at it 
$decimal_places = (($max <= 1) ? 2 : ($max > 3)) 
       ? 0 
       : 1; 

Hangi: sonuçlanan soldan sağa

$decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1); 

// Another way of looking at it 
$decimal_places = ($max <= 1) 
       ? 2 
       : (($max > 3) ? 0 : 1); 

Aksi takdirde üçlü ifadesi değerlendirilir

if ($max <= 1) 
    $cond = 2; 
else 
    $cond = ($max > 3); 

if ($cond) 
    $decimal_places = 0; 
else 
    $decimal_places = 1; 

nedenle $decimal_places bu 1 değerlendirir ve bu durumda 2 hariç $max tüm değerleri için 0 olarak sona erer.

2

kod böylece 2 ve 1 yalnızca 1 < $max <=3 olsun asla

$decimal_places = (($max <= 1) ? 2 : ($max > 3)) ? 0 : 1; 

olarak yürütülür. Bu, koşullu operatörün left-associative olmasıdır. Çözüm:

$decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1); 
1

Sadece parantez koymak ve bu gibi iyi olurdu: Başkaları belirttiği gibi

$decimal_places = ($max <= 1) ? 2 : (($max > 3) ? 0 : 1); 
1

, ayraç, kullanabilirsiniz.
Ancak gerçekte Peki ya bu, okunabilir yapmak istiyorsanız,:

$decimal_places = 
    ($max <= 1) ? 2 : (
    ($max > 3) ? 0 : (
    1 
)); 

Bu hala süper garip görünüyor, ama bu beceriksizlik düzenli bir şekle sahiptir, bu yüzden yaşamak daha kolaydır.

$drink = 'wine'; 
return 
    ($drink === 'wine') ? 'vinyard' : (
    ($drink === 'beer') ? 'brewery' : (
    ($drink === 'juice') ? 'apple tree' : (
    ($drink === 'coffee') ? 'coffeebeans' : (
    'other' 
)))); 

Tabii ki son parantez çiftini çıkartabilirsiniz, ancak bu daha az düzenli görünmesini sağlar.

+0

Gerçekten garip, ama yine de iyi olanı benim için iyi olanı aldım (çünkü anahtarların içindeki ifadeler çok fazla kontrol aldım çünkü ...) – FreshPro

İlgili konular