2010-12-01 26 views
18

Đối với trường hợp rất phổ biến của gán một giá trị cho một biến dựa trên kết quả của một biểu thức Tôi là một fan hâm mộ của các nhà khai thác ternary:có điều kiện giao PHP đánh giá cao

$foo = $bar ? $a : b; 

Tuy nhiên, nếu $ thanh là một tương đối hoạt động đắt tiền và tôi muốn gán kết quả của $ thanh đến $ foo nếu kết quả là truthy, điều này là không hiệu quả:

$foo = SomeClass::bigQuery() ? SomeClass::bigQuery() : new EmptySet(); 

Một lựa chọn là:

$foo = ($result = SomeClass::bigQuery()) ? $result : new EmptySet(); 

Nhưng tôi không muốn có thêm $result ngồi trong bộ nhớ.

Các lựa chọn tốt nhất tôi nhận được là:

$foo = ($foo = SomeClass::bigQuery()) ? $foo : new EmptySet(); 

Hoặc, mà không khai thác ternary:

if(!$foo = SomeClass::bigQuery()) $foo = new EmptySet(); 

Hoặc, nếu các nhà khai thác dòng chảy chương trình không phải là phong cách của bạn:

($foo = SomeClass::bigQuery()) || ($foo = new EmptySet()); 

Vì vậy, nhiều tùy chọn, không phải của họ thực sự thỏa đáng. Mà bạn sẽ sử dụng, và tôi thiếu một cái gì đó thực sự rõ ràng ở đây?

Trả lời

33

PHP 5.3 đã giới thiệu một cú pháp mới để giải quyết chính xác vấn đề này:

$x = expensive() ?: $default; 

Xem documentation:

Kể từ PHP 5.3, chúng ta có thể bỏ qua phần giữa của các nhà điều hành ternary .
Biểu thức expr1 ?: expr3 trả về expr1 nếu expr1 đánh giá là TRUEexpr3 nếu không.

+1

Cá nhân tôi tránh PHP 5.3 chỉ cú pháp và thích '$ x = đắt hơn(); nếu (!$ x) $ x = $ mặc định; ' – meagar

+0

Ồ; Tôi đã chỉ đi để bình luận với "PHP cần phần mở rộng [GNU cho ternaries] (http://stackoverflow.com/questions/3319075/ternary-conditional-operator-behaviour-when-leaving-one-expression-empty)" –

+0

ah ha - bỏ lỡ điều đó trong sách hướng dẫn. Tôi giả định rằng có nghĩa là không có một phương pháp tốt hơn cho 5.2.x (mà tôi phải hỗ trợ trong trung hạn)? – Hamish

8

Bạn có thể cập nhật SomeClass: bigQuery() để trả về một EmptySet() mới thay vì sai?

Sau đó, bạn chỉ có

$foo = SomeClass::bigQuery(); 
+0

+1 cho mã sạch hơn. – Jonah

+0

Điều đó thực sự là sở thích của tôi - thật không may là tôi đang xây dựng trên một thư viện đã mắc lỗi này từ ngày 0 và giờ họ có quá nhiều thứ treo API để sửa lỗi:/ – Hamish

1
$foo = SomeClass::bigQuery(); 
if (!$foo) $foo = new EmptySet(); 

Revision hai, tín dụng @meagar

+0

Thật là khó chịu, cá nhân tôi thích các câu trả lời khác. –

+0

Đã thực hiện một cách để giảm độ dài. – Jonah

+0

Tại sao không 'if (! $ Foo) $ foo = new EmptySet();'? Hơi ít foo. – meagar

1

Một biến thể nhẹ Tùy chọn cuối cùng của bạn:

$ foo = SomeClass :: bigquery() hoặc mới EmptySet(); điều này không thực sự hiệu quả, cảm ơn vì đã chú ý.

Được sử dụng thường xuyên kết hợp với mã mySQL, nhưng dường như luôn bị lãng quên trong các tình huống tương tự:

$result = mysql_query($sql) or die(mysql_error()); 

Mặc dù cá nhân tôi thích một bạn đã đề cập:

if(!$foo = SomeClass::bigQuery()) 
    $foo = new EmptySet(); 
+0

ah, bạn nói đúng là luôn luôn bị lãng quên. Tốt đẹp! – Hamish

+0

Thực ra, cần đọc: '$ foo = SomeClass :: bigQuery() hoặc $ foo = new EmptySet();' tương đương với tùy chọn thứ 3. – Hamish

Các vấn đề liên quan