web-dev-qa-db-ja.com

?:PHPの演算子(「エルビス演算子」)

今日、これをいくつかのPHPコードで見ました:

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

ここで使用されている?:演算子に慣れていません。三項演算子のように見えますが、述部が真である場合に評価する式は省略されています。どういう意味ですか?

235
alpha_juno

左のオペランドが truthy の場合は左のオペランドに評価され、それ以外の場合は右のオペランドに評価されます。

擬似コードでは、

foo = bar ?: baz;

おおよそ解決する

foo = bar ? bar : baz;

または

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

barは1回しか評価されないという違いがあります。

投稿したコード例に示すように、これを使用してfooの「自己チェック」を行うこともできます。

foo = foo ?: bar;

これは、barがnullまたはfalseyの場合、foofooに割り当てます。それ以外の場合は、fooを変更しません。

さらにいくつかの例:

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

ちなみに、それは Elvis operator と呼ばれます。

Elvis operator

466
BalusC

ドキュメント を参照してください:

PHP 5.3以降では、三項演算子の中央部分を省略することができます。式expr1 ?: expr3は、expr1TRUEに評価される場合はexpr1を返し、そうでない場合はexpr3を返します。

53
Yacoby

配列には注意してください。次の理由から、?の後にチェック変数を記述する必要があります。

  $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

更新済み

RFCから。将来的に(PHP 7で)operator Null Coalesce Operator はそれを行います。例えば:

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

もう1つの重要な考慮事項:Elvis Operatorは、Zend Opcacheトークン化プロセスを中断します。これは難しい方法だと思いました!これは後のバージョンで修正されたかもしれませんが、PHP 5.5.38(組み込みのZend Opcache v7.0.6-devを使用)にこの問題が存在することを確認できます。

一部のファイルがZend Opcacheにキャッシュされることを「拒否」する場合、これが理由の1つである可能性があります。

6
Prasad Paradkar

はい、これはPHP 5.3の新機能です。 TRUEと評価された場合はテスト式の値を返し、FALSEと評価された場合は代替値を返します。

3
Atli