web-dev-qa-db-fra.com

?: opérateur ('l'opérateur Elvis') dans PHP

Je l'ai vu aujourd'hui dans un code PHP:

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

Je ne connais pas l'opérateur ?: utilisé ici. Cela ressemble à un opérateur ternaire, mais l'expression à laquelle évaluer si le prédicat est vrai a été omise. Qu'est-ce que ça veut dire?

235
alpha_juno

Il évalue l'opérande gauche si l'opérande gauche est vérité , et l'opérande droit sinon.

En pseudocode,

foo = bar ?: baz;

décide à peu près de

foo = bar ? bar : baz;

ou

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

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

Vous pouvez également l'utiliser pour effectuer un "auto-contrôle" de foo, comme le montre l'exemple de code que vous avez publié:

foo = foo ?: bar;

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

Quelques exemples supplémentaires:

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

En passant, on l’appelle , opérateur Elvis .

Elvis operator

466
BalusC

Voir la documentation :

Depuis PHP 5.3, il est possible de laisser de côté la partie centrale de l'opérateur ternaire. Expression expr1 ?: expr3 renvoie _expr1_ si _expr1_ est évalué à TRUE, et _expr3_ sinon.

53
Yacoby

Soyez prudent avec les tableaux. Nous devons écrire une variable de contrôle après ?, car:

  $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

Mis à jour

De RFC. À l'avenir (dans PHP 7), l'opérateur l'opérateur null de la coalesce le fera, par exemple:

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

Autre considération importante: l’opérateur Elvis rompt le processus de création de jetons Zend Opcache. J'ai trouvé ça à la dure! Bien que cela ait peut-être été corrigé dans les versions ultérieures, je peux confirmer que ce problème existe sous PHP 5.5.38 (avec Zend Opcache v7.0.6-dev intégré).

Si vous trouvez 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 cela vous aidera!

6
Prasad Paradkar

Oui, ceci est nouveau dans PHP 5.3. Il renvoie soit la valeur de l'expression de test si elle est évaluée en tant que TRUE, soit la valeur alternative si elle est évaluée en tant que FALSE.

3
Atli