2010-01-03 3 views
123

J'ai vu aujourd'hui dans un code PHP:: l'opérateur (le « opérateur Elvis ») en PHP

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

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

Répondre

237

Il évalue l'opérande de gauche si l'opérande de gauche est truthy, et l'opérande de droite sinon.

En pseudocode,

foo = bar ?: baz; 

résout à peu près

foo = bar ? bar : baz; 

ou

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

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

Vous pouvez également l'utiliser pour faire un « auto-test » de foo comme le montre l'exemple de code affiché:

foo = foo ?: bar; 

Cela affectera bar-foo si foo est nulle ou Falsey, sinon il laissera foo inchangé.

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

Par ailleurs, il est appelé Elvis operator.

Elvis operator

+7

Assurez-vous que la variable entre parenthèses existe bien, sinon vous allez déclencher une erreur. PHP ne supposera pas simplement avoir une valeur de 'null' ou quoi que ce soit. Justin ' – DanMan

+10

Ce qui est marrant, c'est que cette réponse forme une boucle récursive avec l'article Wiki, ce qui n'explique pas complètement pourquoi il s'appelle l' "opérateur Elvis". – fayerth

+0

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

42

Voir the docs:

Depuis PHP 5.3, il est possible de laisser la partie centrale de l'opérateur ternaire. L'expression expr1 ?: expr3 renvoie expr1 si expr1 est évalué à TRUE et expr3 sinon.

+4

Ils ont besoin d'un nouvel auteur de doc car inévitablement quelqu'un va demander ce qui est arrivé à expr2. Je l'ai juste thunk. –

2

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

+2

Subtilement faux/trompeur; aucun opérande n'a besoin d'être un booléen. Ce qui importe est de savoir si la première valeur est * vérité *, et non si elle est "VRAI". –

+0

@MarkAmery Clarifié. Devrait être assez difficile à mal interpréter de cette façon. – Atli

7

Soyez prudent avec les tableaux. Nous devons écrire une variable après vérification ?, 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 l'avenir (en PHP 7) opérateur Null Coalesce Operator le fera, par exemple:

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

Cela ne répond pas à la question, et n'est pas utile à quiconque essaie de comprendre quand utiliser l'opérateur Elvis. –

+3

@Mark Amery hmm .. Vraiment? N'est-ce pas utile? Avez-vous vraiment travaillé avec PHP et regardé des milliers de cas en utilisant pour accéder aux vars de tableau avec ternary? Ok, j'ai changé le texte à "Soyez prudent avec les tableaux .." – voodoo417

+0

donc coalesce nulle et elvis sont les mêmes? –

2

Une autre considération importante: Le casse opérateur Elvis le processus de tokenization Zend Opcache.J'ai trouvé ça à la dure! Bien que cela puisse avoir été corrigé dans les versions ultérieures, je peux confirmer que ce problème existe dans 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, cela peut être une des raisons ... Espérons que cela aide!