2010-04-17 30 views
14

tôi đã được yêu cầu thực hiện thao tác này sử dụng nhà điều hành ternary:hoạt động không bình thường ternary

$test='one'; 

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

nào in hai (kiểm tra bằng php).

Tôi vẫn chưa chắc chắn về logic này. Xin vui lòng, bất cứ ai có thể cho tôi biết logic cho việc này.

+3

oh my ... đôi mắt của tôi ... được đốt .... nó không thể là vô hình ... –

+0

đó là không tệ lắm. Trong các ngôn ngữ khác, đây sẽ là một thành ngữ. Trong PHP, nhờ vào sự kết hợp nhà điều hành kém được lựa chọn của nó, nó là một cái bẫy. – bobince

+0

@bobince đã thử nó bằng các ngôn ngữ khác hoặc bạn chỉ giả định – nik

Trả lời

15

Vâng,? và: có ưu tiên bình đẳng, vì vậy PHP sẽ phân tích trái sang phải đánh giá từng chút lần lượt:

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

Đầu tiên $test == 'one' trả về true, vì vậy các dấu ngoặc đầu tiên có giá trị 'one'. Bây giờ thứ hai được đánh giá như sau:

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

'một' là đúng (chuỗi không trống), vì vậy 'hai' là kết quả cuối cùng.

+0

Đây là giải thích đúng nhất ngắn nhất :) +1. –

+0

rite nói Pekka – nik

+0

+1 cho ngắn gọn và rõ ràng của lời giải thích (một sự kết hợp khó khăn) –

1

PHP CỦA documentation nói:

Lưu ý: Chúng tôi đề nghị bạn tránh "xếp chồng" biểu ternary. hành vi của PHP khi sử dụng nhiều hơn một nhà điều hành ternary trong một tuyên bố duy nhất là không rõ ràng:

Ví dụ # 3 không rõ ràng hành vi ternary

<?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. 
?> 

Nếu bạn đặt ngoặc xung quanh các tuyên bố sai sự thật, nó in one:

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

Hoạt động liên quan đến lồng nhau được gộp! Lời giải thích ở trên cho thấy lý do.

Về cơ bản đây là logic:

is $test == 'one' 

    if TRUE then echo 'one' 

    else is $test == 'two' 

     if TRUE then echo 'two' 

     else echo three 
+0

Tôi nghĩ bạn đang đi đúng hướng và có giải thích tốt nhất nhưng logic của bạn không thêm vào, vì nó không xuất ra 'one' –

+0

giải thích của Filix Kling trả lời câu hỏi đó mặc dù nó không có ý nghĩa tại sao dấu ngoặc đơn là cần thiết. –

5

Nó hoạt động một cách chính xác khi bạn sử dụng dấu ngoặc:

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

Tôi không hiểu nó 100% nhưng không có dấu ngoặc, để người phiên dịch, báo cáo kết quả phải có dạng như sau:

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

kết quả của điều kiện đầu tiên dường như được trả lại là kết quả của toàn bộ hoạt động ternary.

1

Tôi nghĩ rằng nó được đánh giá như thế này:

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

($ test == 'một' 'one': $ test == 'hai') không phải là zero/null, vì vậy ' hai' là logic đầu ra

nếu bạn muốn nó hoạt động chính xác, viết:

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

Về cơ bản thông dịch viên đánh giá biểu thức này từ trái sang phải, vì vậy:

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

được hiểu như là

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

Và biểu hiện trong paratheses để đánh giá đúng, vì cả hai 'one' và 'hai 'không phải là null/o/hình thức sai khác. Vì vậy, nếu nó trông giống như:

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

Nó sẽ in ba. Để làm cho nó hoạt động tốt, bạn nên quên kết hợp các toán tử bậc ba và sử dụng ifs/switch thông thường cho logic phức tạp hơn, hoặc ít nhất là sử dụng dấu ngoặc, cho trình thông dịch hiểu logic của bạn và không thực hiện kiểm tra theo cách LTR chuẩn:

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... 
} 
+0

Chính xác, tôi đã về để gửi nó, tôi tìm thấy nó trong tài liệu php. :) –

1

khai thác ternary được thực hiện theo thứ tự xuất hiện, do đó bạn thực sự có:

echo ($test == 'one' ? 'one' : $test == 'two') ? 'two' : 'three'; 
Các vấn đề liên quan