2010-01-03 37 views
123

tôi thấy ngày hôm nay tại một số mã PHP:: nhà điều hành (của Elvis điều hành ') trong PHP

$items = $items ?: $this->_handle->result('next', $this->_result, $this); 

Tôi không quen thuộc với các nhà điều hành ?: đang được sử dụng ở đây. Nó trông giống như một toán tử bậc ba, nhưng biểu thức để đánh giá nếu vị từ là đúng đã bị bỏ qua. Nó có nghĩa là gì?

Trả lời

237

Nó đánh giá toán hạng bên trái nếu toán hạng bên trái là truthy và toán hạng bên phải.

Trong giả,

foo = bar ?: baz; 

khoảng quyết tâm

foo = bar ? bar : baz; 

hoặc

if (bar) { 
    foo = bar; 
} else { 
    foo = baz; 
} 

với sự khác biệt mà bar sẽ chỉ được đánh giá một lần.

Bạn cũng có thể sử dụng để làm một "tự kiểm tra" của foo như thể hiện trong ví dụ mã bạn được đăng:

foo = foo ?: bar; 

này sẽ gán bar-foo nếu foo là null hoặc falsey, ngược lại nó sẽ để lại foo không thay đổi.

Một số chi tiết ví dụ:

<?php 
    var_dump(5 ?: 0); // 5 
    var_dump(false ?: 0); // 0 
    var_dump(null ?: 'foo'); // 'foo' 
    var_dump(true ?: 123); // true 
    var_dump('rock' ?: 'roll'); // 'rock' 
?> 

Bằng cách này, nó được gọi là các Elvis operator.

Elvis operator

+7

Hãy chắc chắn rằng các biến trong ngoặc đơn tồn tại mặc dù, hoặc bạn sẽ đưa ra một lỗi. PHP sẽ không chỉ giả sử nó có giá trị 'null' hoặc bất cứ thứ gì. Chỉ cần sayin ' – DanMan

+10

Điều thú vị là câu trả lời này tạo thành một vòng lặp đệ quy với bài viết Wiki, điều này không giải thích đầy đủ tại sao nó được gọi là "toán tử Elvis". – fayerth

+0

http://emoticon.wikia.com/wiki/Elvis_Presley –

42

Xem the docs:

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.

+4

Họ cần một người viết doc mới vì chắc chắn ai đó sẽ hỏi điều gì đã xảy ra với expr2. Tôi chỉ thunk nó. –

2

Có, đây là tính năng mới trong PHP 5.3. Nó trả về giá trị của biểu thức kiểm tra nếu nó được đánh giá là TRUE, hoặc giá trị thay thế nếu nó được đánh giá là FALSE.

+2

Subtly sai/gây hiểu nhầm; toán hạng không phải là boolean. Điều quan trọng là liệu giá trị đầu tiên có đúng không * không phải là 'TRUE'. –

+0

@MarkAmery Làm rõ. Nên khá khó hiểu sai nó theo cách này. – Atli

7

Hãy cẩn thận với mảng. Chúng ta phải viết một biến kiểm tra sau ?, bởi vì:

$params = ['param1' => 'value1', 
      'param2' => 'value2', 
      'param3' => 'value3',]; 

    $param1 = isset($params['param1'])?:null; 
    $param2 = !empty($params['param2'])?:null; 
    $param3 = $params['param3']?:null; // get E_NOTICE, if $params['param3'] eq false 

    var_dump($param1,$param2,$param3); 
    true // would like to expect `value1` 
    true // would like to expect `value2` 
    param3 // properly, but problem above 

Cập nhật

Từ RFC. Trong tương lai (trong PHP 7) điều hành Null Coalesce Operator sẽ làm điều đó, ví dụ:

$param1 = $params['param1'] ?? null; 
// Equivalent to: $param1 = isset($params['param1']) ? $params['param1'] : null; 
+1

Điều này không trả lời câu hỏi, cũng không hữu ích đối với bất kỳ ai cố gắng hiểu khi nào sử dụng toán tử Elvis. –

+3

@Mark Amery hmm .. Thật sao? Isn 't helpfull? Bạn có thực sự làm việc với PHP và xem xét hàng ngàn trường hợp trong việc sử dụng để truy cập vào các mảng của vars với ternary? Ok, tôi đã thay đổi văn bản thành "Hãy cẩn thận với mảng .." – voodoo417

+0

do đó, null kết hợp và elvis giống nhau? –

2

Một yếu tố quan trọng: Các Elvis hành phá vỡ quá trình tokenization Zend Opcache.Tôi thấy điều này một cách khó khăn! Trong khi điều này có thể đã được sửa trong các phiên bản sau, tôi có thể xác nhận vấn đề này tồn tại trong PHP 5.5.38 (với Zend Opcache v7.0.6-dev).

Nếu bạn thấy rằng một số tệp của bạn 'từ chối' được lưu vào bộ đệm trong Zend Opcache, đây có thể là một trong những lý do ... Hy vọng điều này sẽ hữu ích!