web-dev-qa-db-fra.com

Fonction de coalescence pour PHP?

De nombreux langages de programmation ont une fonction de fusion (renvoie la première valeur non NULL, exemple ). PHP, malheureusement en 2009, ne fonctionne pas.

Quelle serait une bonne façon d'en implémenter une dans PHP jusqu'à PHP lui-même obtient une fonction de fusion)?

129
mikl

Il y a un nouvel opérateur dans php 5.3 qui fait ceci: ?:

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

// B
echo '' ?: 'B';

// B
echo false ?: 'B';

// B
echo null ?: 'B';

Source: http://www.php.net/ChangeLog-5.php#5.3.

189
Kevin

PHP 7 a introduit un vrai opérateur de fusion :

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

Si la valeur avant le ?? n'existe pas ou est null la valeur après le ?? est pris.

L'amélioration par rapport aux ?: est que l'opérateur ?? gère également les variables non définies sans lancer un E_NOTICE.

62
flori

Premier coup pour "php coalesce" sur google.

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

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

29
Will Shaver

J'aime vraiment l'opérateur?:. Malheureusement, il n'est pas encore implémenté sur mon environnement de production. J'utilise donc l'équivalent de ceci:

function coalesce() {
  return array_shift(array_filter(func_get_args()));
}
18
Ethan Kent

Il convient de noter qu'en raison du traitement par PHP des variables non initialisées et des indices de tableau, tout type de fonction de fusion est d'une utilité limitée. J'adorerais pouvoir faire ça:

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

Mais cela entraînera, dans la plupart des cas, une erreur PHP avec un E_NOTICE. Le seul moyen sûr de tester l'existence d'une variable avant de l'utiliser est de l'utiliser directement dans empty () ou isset L'opérateur ternaire suggéré par Kevin est la meilleure option si vous savez que toutes les options de votre fusion sont connues pour être initialisées.

9
Andrew

Assurez-vous d'identifier exactement comment vous souhaitez que cette fonction fonctionne avec certains types. PHP a une grande variété de fonctions de vérification de type ou similaires, alors assurez-vous de savoir comment elles fonctionnent. Ceci est un exemple de comparaison de is_null () et empty ()

$testData = array(
  'FALSE'   => FALSE
  ,'0'      => 0
  ,'"0"'    => "0"  
  ,'NULL'   => NULL
  ,'array()'=> array()
  ,'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>';
}

Comme vous pouvez le voir, empty () renvoie true pour tous ces éléments, mais is_null () ne le fait que pour 2 d'entre eux.

6
Peter Bailey

Je développe la réponse postée par Ethan Kent . Cette réponse supprimera les arguments non nuls qui sont évalués à faux en raison du fonctionnement interne de array_filter , ce qui n'est pas ce que fait généralement une fonction coalesce. Par exemple:

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

Oops

Pour surmonter cela, un deuxième argument et une définition de fonction sont nécessaires. La fonction appelable est chargée de dire array_filter d'ajouter ou non la valeur actuelle du tableau au tableau résultat:

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

function coalesce(){
    // pass callable to array_filter
    return array_shift(array_filter(func_get_args(), 'not_null'));
}

Ce serait bien si vous pouviez simplement passer isset ou 'isset' comme deuxième argument de array_filter, mais pas de chance.

2
Madbreaks

J'utilise actuellement cela, mais je me demande si cela ne pourrait pas être amélioré avec certaines des nouvelles fonctionnalités de PHP 5.

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

PHP 5.3+, avec fermetures:

function coalesce()
{
    return array_shift(array_filter(func_get_args(), function ($value) {
        return !is_null($value);
    }));
}

Démo: https://eval.in/187365

0
Paulo Freitas