2010-01-03 46 views
123

Ho visto questo oggi in qualche codice PHP::? Operator (il 'Elvis' operatore') in PHP

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

Non ho dimestichezza con l'operatore ?: in uso qui. Sembra un operatore ternario, ma l'espressione da valutare se il predicato è vero è stata omessa. Cosa significa?

risposta

237

Valuta l'operando di sinistra se l'operando di sinistra è truthy e l'operando di destra in caso contrario.

In pseudocodice,

foo = bar ?: baz; 

risolve all'incirca

foo = bar ? bar : baz; 

o

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

con la differenza che bar saranno valutate solo una volta.

È anche possibile utilizzare questo per fare un "self-check" della foo come dimostra l'esempio di codice che avete inviato:

foo = foo ?: bar; 

Questo assegnerà bar-foo se foo è nulla o Falsey, altrimenti lascerà foo invariato.

Alcuni altri esempi:

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

Tra l'altro, si chiama il Elvis operator.

Elvis operator

+7

Assicurati che la variabile tra parentesi esista, o che stai per generare un errore. PHP non supporterà solo che abbia un valore di 'null' o altro. Basta dire ' – DanMan

+10

Ciò che è divertente è che questa risposta forma un ciclo ricorsivo con l'articolo Wiki, che non spiegava pienamente perché è chiamato "operatore Elvis". – fayerth

+0

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

42

Vedi the docs:

Dal PHP 5.3, è possibile lasciare fuori la parte centrale l'operatore ternario. Espressione expr1 ?: expr3 restituisce expr1 se expr1 restituisce TRUE e expr3 in caso contrario.

+4

Hanno bisogno di un nuovo doc writer perché inevitabilmente qualcuno chiederà cosa è successo a expr2. L'ho solo mandato. –

2

Sì, questo è nuovo in PHP 5.3. Restituisce il valore dell'espressione di test se è valutato come TRUE, o il valore alternativo se è valutato come FALSE.

+2

Sottilmente sbagliato/fuorviante; nessuno degli operandi deve essere un booleano. Ciò che importa è se il primo valore è * verità *, non se sia "VERO". –

+0

@MarkAmery Chiarito. Dovrebbe essere abbastanza difficile interpretarlo male in questo modo. – Atli

7

stare attenti con gli array. Dobbiamo scrivere una variabile di controllo dopo ?, perché:

$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 

Aggiornato

Da RFC. In futuro (in PHP 7) operatore Null Coalesce Operator lo farà, per esempio:

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

Questo non risponde alla domanda, né è utile a nessuno che tenti di capire quando utilizzare l'operatore Elvis. –

+3

@Mark Amery hmm .. Davvero? Non è utile? Hai davvero lavorato con PHP e guardi a migliaia di casi in cui utilizzare per accedere ai vars dell'array con ternario? Ok, ho cambiato il testo in "Attento con gli array .." – voodoo417

+0

quindi coalesce nullo ed elvis sono uguali? –

2

Un'altra considerazione importante: l'operatore Elvis rompe il processo di tokenizzazione Zend Opcache.L'ho trovato nel modo più duro! Anche se questo potrebbe essere stato risolto nelle versioni successive, posso confermare che questo problema esiste in PHP 5.5.38 (con Zend Opcache v7.0.6-dev integrato).

Se si trova che alcuni dei file "rifiutano" di essere memorizzati nella cache in Zend Opcache, questo potrebbe essere uno dei motivi ... Spero che questo aiuti!