?:PHPの演算子(「Elvis演算子」)


258

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

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

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

回答:


529

左のオペランドがtrueyの場合は左のオペランドに評価され、そうでない場合は右のオペランドに評価されます。

擬似コードでは、

foo = bar ?: baz;

大まかに解決する

foo = bar ? bar : baz;

または

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

違いbarは1回だけ評価されます。

これを使用して、foo投稿したコード例に示されているように「セルフチェック」を行うこともできます。

foo = foo ?: bar;

これはif がnullまたはfalseに割り当てbarられ、それ以外の場合は変更されません。foofoofoo

さらにいくつかの例:

<?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オペレーター


11
ただし、括弧内の変数が存在することを確認してください。そうしないと、エラーが発生します。PHPは、nullそれが何かの値を持つことを前提とするだけではありません。Just sayin '
DanMan

20
おかしいのは、この回答がWiki記事と再帰ループを形成することです。この回答は、「Elvisオペレーター」と呼ばれる理由を完全には説明していません。
appearing.amusing

41
少し操作を少なくし、もう少し表現をお願いします。
aalaap 2016年

2
なぜ||。それでblah || 'default'
Noitidart 2018

10
@Noitidart左端の真のオペランドを返すJSとは異なり、PHPでは||演算子は常にブール値を返します。
ksadowski

58

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

PHP 5.3以降、三項演算子の中間部分を省略することが可能です。式expr1 ?: expr3expr1、にexpr1評価された場合にTRUEexpr3そうでない場合に戻ります。


10
必然的に誰かがexpr2に何が起こったかを尋ねるので、彼らは新しいドキュメントライターを必要とします。私はちょうどそれをサンクしました。
John K

7
一体何ですか?PHP 7にアップグレードした直後に、これを見つけました。私は何年もこれを使っていたはずです!
Buttle Butkus

TBH、ドキュメントは正しいです。何が起こったかというexpr2と、それが消えただけで、評価されていません。$this->expensiveComputation() ?: "nope"と同じではありません$this->expensiveComputation() ? $this->expensiveComputation() : "nope"-expr1は一度だけ評価されます。
Piskvorが

18

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

  $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では)演算子Null Coalesce Operatorがそれを実行します。次に例を示します。

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

1
これは質問の答えにはなりませんし、Elvis Operatorをいつ使用するかを理解しようとする人にとっても役に立ちません。
Mark Amery 2015

7
@Mark Ameryうーん..本当に?役に立ちませんか?あなたは本当にPHPを使用して、3値で配列の変数にアクセスするために使用する何千ものケースを見てみましたか?
わかり

null合体とエルビスは同じですか?
Nabeel Khan、2016

7
@NabeelKhanいいえ!そのため、PHP imoではElvis演算子が役に立たなくなります。Elvis演算子は式を評価し、それが真の場合はそれを返し、それ以外の場合は最後の部分を返します。PHPは型が低いため、多くのことがtrueまたはfalseになり、ほとんどの場合、期待どおりに動作しません。つまり、Elvis演算子を使用して変数が定義されていない場合、デフォルト値を変数に設定する必要があります。PHPは0が定義されていないことを示しますが、0が必要な場合があります...そのため、PHP 7はNull Coalesce演算子を取得します、それは厳密にnullに対して変数をテストするので、PHPは0が未定義ではないと言うでしょう。
グレゴワールD.16年

1
@FuscaSoftware:このようなエラー抑制を使用することは、私の経験では良い考えではありません。
TeeHays

8

もう1つの重要な考慮事項:ElvisオペレーターはZend Opcacheトークン化プロセスを中断します。私はこれを難しい方法で見つけました!これは後のバージョンで修正されている可能性がありますが、この問題がPHP 5.5.38(組み込みのZend Opcache v7.0.6-dev)に存在することを確認できます。

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


4

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


2
微妙に間違っている/誤解を招く; どちらのオペランドもブール値である必要はありません。重要なのは、最初の値が真実かどうかではなく真実かどうかTRUEです。
Mark Amery、2015

@MarkAmeryを明確化。このように誤解するのはかなり難しいはずです。
Atli
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.