: opérateur (l' "opérateur Elvis") en PHP

j'ai vu ça aujourd'hui dans un code PHP:

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

Je ne suis pas familier avec l'opérateur ?: utilisé ici. Il ressemble à un opérateur ternaire, mais l'expression à évaluer si le prédicat est vrai a été omis. Ça veut dire quoi?

169
demandé sur Mark Amery 2010-01-03 03:10:58

5 réponses

il évalue à l'opérande de gauche si l'opérande de gauche est truthy , et l'opérande de droite autrement.

en pseudo-code,

foo = bar ?: baz;

se résout grossièrement en

foo = bar ? bar : baz;

ou

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

à la différence que bar ne sera évalué qu'une seule fois.

vous pouvez également utiliser ceci pour faire une "auto-vérification" de foo comme démontré dans l'exemple de code que vous avez posté:

foo = foo ?: bar;

assignera bar à foo si foo est nul ou falsey, sinon il laissera foo inchangé.

quelques autres exemples:

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

soit dit en passant, ça s'appelle le Elvis operator .

Elvis operator

328
répondu BalusC 2014-05-24 17:37:15

voir the docs :

depuis PHP 5.3, il est possible d'omettre la partie centrale de l'opérateur ternaire. L'Expression expr1 ?: expr3 renvoie expr1 si expr1 valeur TRUE , et expr3 dans le cas contraire.

46
répondu Yacoby 2014-05-24 17:08:01

faites attention aux tableaux. Nous devons écrire une variable de contrôle après ? , parce que:

  $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

mise à Jour

de RFC. Dans le futur (en PHP 7) l'opérateur L'opérateur nul Coalesce le fera, par exemple:

$param1 = $params['param1'] ?? null;
// Equivalent to:  $param1 = isset($params['param1']) ? $params['param1'] : null;
12
répondu voodoo417 2015-12-14 18:33:30

autre considération importante: L'opérateur Elvis casse le processus de tokenisation Zend Opcache. J'ai trouvé cela à la dure! Bien que cela puisse avoir été corrigé dans des versions ultérieures, je peux confirmer que ce problème existe dans PHP 5.5.38 (avec Zend Opcache V7 intégré.0.6-dev).

si vous constatez que certains de vos fichiers 'refusent' d'être mis en cache dans Zend Opcache, c'est peut-être l'une des raisons... Espérons que cette aide!

4
répondu Prasad Paradkar 2017-02-16 18:10:28

Oui, c'est nouveau en PHP 5.3. Il renvoie soit la valeur de l'expression test si elle est évaluée comme vraie, soit la valeur alternative si elle est évaluée comme fausse.

3
répondu Atli 2015-02-17 09:05:45