Funzione di coalescenza per PHP?

Molti linguaggi di programmazione hanno una function di coalescenza (restituisce il primo valore non NULL, esempio ). PHP, purtroppo, non lo fa.

Quale sarebbe un buon modo per implementarne uno in PHP?

C'è un nuovo operatore in php 5.3 che fa questo: ?:

 // A echo 'A' ?: 'B'; // B echo '' ?: 'B'; // B echo false ?: 'B'; // B echo null ?: 'B'; 

Fonte: http://www.php.net/ChangeLog-5.php#5.3.0

PHP 7 ha introdotto un vero operatore di coalescenza :

 echo $_GET['doesNotExist'] ?? 'fallback'; // prints 'fallback' 

Se il valore prima del ?? non esiste o è null il valore dopo il ?? è preso.

Il miglioramento rispetto al citato ?: Operatore è, che il ?? gestisce anche le variables non definite senza lanciare un E_NOTICE .

Primo hit per "php coalesce" su google.

 function coalesce() { $args = func_get_args(); foreach ($args as $arg) { if (!empty($arg)) { return $arg; } } return NULL; } 

http://drupial.com/content/php-coalesce

Mi piace davvero l'operatore?:. Sfortunatamente, non è ancora stato implementato nel mio ambiente di produzione. Quindi uso l'equivalente di questo:

 function coalesce() { return arrays_shift(arrays_filter(func_get_args())); } 

Vale la pena notare che, a causa del trattamento da parte di PHP delle variables non finalizzate e degli indici di arrays, qualsiasi tipo di function di coalescenza è di uso limitato. Mi piacerebbe essere in grado di farlo:

 $id = coalesce($_GET['id'], $_SESSION['id'], null); 

Ma questo, nella maggior parte dei casi, causerà errori di PHP con un E_NOTICE. L'unico modo sicuro per testare l'esistenza di una variabile prima di usarla è usarlo direttamente in empty () o isset (). L'operatore ternario suggerito da Kevin è l'opzione migliore se si sa che tutte le opzioni della coalesce sono note per essere inizializzate.

Assicurati di identificare esattamente come vuoi che questa function funzioni con determinati tipi. PHP ha una vasta gamma di funzioni di controllo dei tipi o simili, quindi assicurati di sapere come funzionano. Questo è un confronto di esempio di is_null () e empty ()

 $testData = arrays( 'FALSE' => FALSE ,'0' => 0 ,'"0"' => "0" ,'NULL' => NULL ,'arrays()'=> arrays() ,'new stdClass()' => new stdClass() ,'$undef' => $undef ); foreach ( $testData as $key => $var ) { echo "$key " . (( empty( $var ) ) ? 'is' : 'is not') . " empty<br>"; echo "$key " . (( is_null( $var ) ) ? 'is' : 'is not') . " null<br>"; echo '<hr>'; } 

Come puoi vedere, empty () restituisce true per tutti questi, ma is_null () lo fa solo per 2 di essi.

Sto espandendo la risposta pubblicata da Ethan Kent . Quella risposta eliminerà argomenti non nulli che valutano in falso a causa del funzionamento interno di arrays_filter , che non è quello che tipicamente fa una function di coalesce . Per esempio:

 echo 42 == coalesce(null, 0, 42) ? 'Oops' : 'Hooray'; 

Spiacenti

Per superare questo, sono necessari un secondo argomento e una definizione di function. La function callable è responsabile di comunicare a arrays_filter se aggiungere o less il valore dell'arrays corrente all'arrays risultato:

 // "callable" function not_null($i){ return !is_null($i); // strictly non-null, 'isset' possibly not as much } function coalesce(){ // pass callable to arrays_filter return arrays_shift(arrays_filter(func_get_args(), 'not_null')); } 

Sarebbe bello se si potesse semplicemente passare isset o 'isset' come secondo argomento a arrays_filter , ma non così fortunato.

Saluti

Attualmente sto usando questo, ma mi chiedo se non potrebbe essere migliorato con alcune delle nuove funzionalità di PHP 5.

 function coalesce() { $args = func_get_args(); foreach ($args as $arg) { if (!empty($arg)) { return $arg; } } return $args[0]; } 

PHP 5.3+, con chiusure:

 function coalesce() { return arrays_shift(arrays_filter(func_get_args(), function ($value) { return !is_null($value); })); } 

Demo: https://eval.in/187365