Opérateur ternaire PHP vs opérateur coalescent null

Quelqu'un peut-il expliquer les différences entre l'opérateur ternaire sténographie (?:) et l'opérateur coalescent null (??) en PHP?

Quand se comportent-ils différemment et quand de la même manière (si cela arrive même)?

$a ?: $b

VS.

$a ?? $b
164
demandé sur Andrew 2016-01-03 01:23:40

9 réponses

Lorsque votre premier argument est null, ils sont fondamentalement les mêmes sauf que la coalescence null ne produira pas de E_NOTICE lorsque vous avez une variable indéfinie. Les documents de migration PHP 7.0 {[13] } ont ceci à dire:

L'opérateur coalescent nul (??) a été ajouté comme sucre syntaxique pour le cas courant d'avoir besoin d'utiliser un ternaire en conjonction avec la fonction isset(). Il retourne son premier opérande s'il existe et n'est pas NULL; sinon il retourne sa seconde opérande.

Voici un exemple de code pour le démontrer:

<?php

$a = null;

print $a ?? 'b';
print "\n";

print $a ?: 'b';
print "\n";

print $c ?? 'a';
print "\n";

print $c ?: 'a';
print "\n";

$b = array('a' => null);

print $b['a'] ?? 'd';
print "\n";

print $b['a'] ?: 'd';
print "\n";

print $b['c'] ?? 'e';
print "\n";

print $b['c'] ?: 'e';
print "\n";

Et c'est la sortie:

b
b
a

Notice: Undefined variable: c in /in/apAIb on line 14
a
d
d
e

Notice: Undefined index: c in /in/apAIb on line 33
e

Les lignes qui ont l'avis sont celles où j'utilise l'opérateur ternaire raccourci par opposition à l'opérateur coalescent null. Cependant, même avec L'avis, PHP donnera la même réponse.

Exécuter le code: https://3v4l.org/McavC

Bien sûr, cela suppose toujours que le premier argument est null. Lorsqu'il n'est plus null, alors vous vous retrouvez avec des différences en ce que l'opérateur ?? retournerait toujours le premier argument alors que le raccourci ?: ne le ferait que si le premier argument était vrai, et cela dépend de la façon dont PHP taperait les choses à un booléen .

Donc:

$a = false ?? 'f';
$b = false ?: 'g';

, Serait alors $a être égal à false et $b égal à 'g'.

170
répondu MasterOdin 2017-11-18 16:57:29

Si vous utilisez l'opérateur ternaire de raccourci comme celui-ci, cela provoquera un avis si $_GET['username'] n'est pas défini:

$val = $_GET['username'] ?: 'default';

Donc, à la place, vous devez faire quelque chose comme ceci:

$val = isset($_GET['username']) ? $_GET['username'] : 'default';

L'opérateur null coalescent {[14] } est équivalent à l'instruction ci-dessus, et retournera 'default' si $_GET['username'] n'est pas défini ou est null:

$val = $_GET['username'] ?? 'default';

Notez que Il ne vérifie pas la véracité. Il vérifie seulement s'il est défini et non null.

Vous pouvez également le faire, et le premier défini (défini et non null) la valeur sera renvoyée:

$val = $input1 ?? $input2 ?? $input3 ?? 'default';

Maintenant, c'est un bon opérateur coalescent.

47
répondu Andrew 2017-06-23 13:24:12

La principale différence est que

  1. Opérateur Ternaire expression expr1 ?: expr3 retourne expr1 si expr1 donne TRUE mais d'autre part opérateur Coalescent Null expression (expr1) ?? (expr2) évalue à expr1 si expr1 est pas NULL

  2. Ternaire Opérateur expr1 ?: expr3 émettre un avis si la gauche valeur (expr1) n'existe pas, mais d'autre part Null Coalescence de l'Opérateur (expr1) ?? (expr2) En particulier, ne ne pas émettre un avis si la valeur de gauche (expr1) n'existe pas, tout comme isset().

  3. TernaryOperator est associativité à gauche

    ((true ? 'true' : false) ? 't' : 'f');
    

    L'opérateur Coalescent Null est associatif droit

    ($a ?? ($b ?? $c));
    

Maintenant, expliquons la différence entre par exemple:

Opérateur Ternaire (?:)

$x='';
$value=($x)?:'default';
var_dump($value);

// The above is identical to this if/else statement
if($x){
  $value=$x;
}
else{
  $value='default';
}
var_dump($value);

Opérateur Coalescent Null (??)

$value=($x)??'default';
var_dump($value);

// The above is identical to this if/else statement
if(isset($x)){
  $value=$x;
}
else{
  $value='default';
}
var_dump($value);

Voici la table qui expliquer la différence et la similitude entre les '??' et ?:

entrez la description de l'image ici

Note spéciale: l'opérateur coalescent nul et l'opérateur ternaire est un l'expression, et qu'il n'évalue pas à une variable, mais à la résultat d'une expression. C'est important de savoir si vous voulez renvoie une variable par référence. La déclaration de retour $ foo ?? $bar; et retour $ var = = 42 ? $a: $b; dans une fonction de retour par référence donc pas de travail et un d'avertissement est émis.

20
répondu Dhairya Lakhera 2017-11-18 11:12:53

Les deux se comportent différemment en ce qui concerne le traitement dynamique des données.

Si la variable est vide ( " ) la coalescence null traitera la variable comme vraie mais l'opérateur ternaire raccourci ne le fera pas.et c'est quelque chose à avoir à l'esprit.

$a = NULL;
$c = '';

print $a ?? '1b';
print "\n";

print $a ?: '2b';
print "\n";

print $c ?? '1d';
print "\n";

print $c ?: '2d';
print "\n";

print $e ?? '1f';
print "\n";

print $e ?: '2f';

Et la sortie:

1b
2b

2d
1f

Notice: Undefined variable: e in /in/ZBAa1 on line 21
2f

Lien: https://3v4l.org/ZBAa1

12
répondu Chazy Chaz 2016-05-23 19:07:47

A exécuté le ci-dessous en mode interactif php (php -a sur le terminal). Le commentaire sur chaque ligne montre le résultat.

var_dump (false ?? 'value2');   # bool(false)
var_dump (true  ?? 'value2');   # bool(true)
var_dump (null  ?? 'value2');   # string(6) "value2"
var_dump (''    ?? 'value2');   # string(0) ""
var_dump (0     ?? 'value2');   # int(0)

var_dump (false ?: 'value2');   # string(6) "value2"
var_dump (true  ?: 'value2');   # bool(true)
var_dump (null  ?: 'value2');   # string(6) "value2"
var_dump (''    ?: 'value2');   # string(6) "value2"
var_dump (0     ?: 'value2');   # string(6) "value2"

Voici donc mon interprétation:

1. L'Opérateur Coalescent Null- ??:

  • ?? est comme une "porte" qui ne laisse passer NULL que .
  • , de Sorte, elle renvoie toujours premier paramètre, à moins que premier paramètre se trouve être NULL.
  • cela signifie que ?? est identique à ( !isset() || is_null() )

2. L'Opérateur Ternaire - ?:

  • ?: c'est comme une porte qui vous permet de anything falsy par - y compris NULL
  • 0, empty string, NULL, false, !isset(), empty() .. tout ce qui sent faux
  • tout comme l'opérateur ternaire classique: echo ($x ? $x : false)
  • NOTE: {[13] } lancera PHP NOTICE sur des variables non définies (unset ou !isset())

3. Alors, docteur, quand dois-je utiliser ?? et ?: ..

  • je suis je plaisante - Je ne suis pas médecin et c'est juste une interprétation
  • j'utiliserais ?: Quand
    • faire empty($x) vérifie
    • L'opération ternaire classique comme !empty($x) ? $x : $y peut être raccourcie à $x ?: $y
    • {[34] } peut être raccourci à fn(($x ?: $y))
  • j'utiliserais ?? quand
    • je veux faire une vérification !isset() || is_null()
    • par exemple vérifier si un objet existe - $object = $object ?? new objClassName();

4. Opérateurs d'empilage ...

  1. L'opérateur ternaire peut être empilé ...

    echo 0 ?: 1 ?: 2 ?: 3; //1
    echo 1 ?: 0 ?: 3 ?: 2; //1
    echo 2 ?: 1 ?: 0 ?: 3; //2
    echo 3 ?: 2 ?: 1 ?: 0; //3
    
    echo 0 ?: 1 ?: 2 ?: 3; //1
    echo 0 ?: 0 ?: 2 ?: 3; //2
    echo 0 ?: 0 ?: 0 ?: 3; //3
    

    Source et crédit pour ce code

    C'est essentiellement une séquence de:

    if( truthy ) {}
    else if(truthy ) {}
    else if(truthy ) {}
    ..
    else {}
    
  2. L'opérateur Coalese Null peut être empilé ...

    $v = $x ?? $y ?? $z; 
    

    C'est une séquence de:

    if(!isset($x) || is_null($x) ) {} 
    else if(!isset($y) || is_null($y) ) {}
    else {}
    
  3. En utilisant l'empilement, je peux raccourcir ceci:

    if(!isset($_GET['name'])){
       if(isset($user_name) && !empty($user_name)){
          $name = $user_name;
       }else {
          $name = 'anonymous';
       }
    } else { 
       $name = $_GET['name'];
    }
    

    Pour cela:

    $name = $_GET['name'] ?? $user_name ?: 'anonymous';
    

    Cool, non? :-)

12
répondu a20 2018-03-24 15:28:44

Faites défiler vers le bas sur ce lien et voir la section, il vous donne un exemple comparatif comme on le voit ci-dessous:

<?php
/** Fetches the value of $_GET['user'] and returns 'nobody' if it does not exist. **/
$username = $_GET['user'] ?? 'nobody';
/** This is equivalent to: **/
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

/** Coalescing can be chained: this will return the first defined value out of $_GET['user'], $_POST['user'], and 'nobody'. **/
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>

Cependant, il n'est pas conseillé d'enchaîner les opérateurs car il est plus difficile de comprendre le code lors de sa lecture ultérieure.

L'opérateur coalescent nul (??) a été ajouté comme sucre syntaxique pour le cas courant d'avoir besoin d'utiliser un ternaire en conjonction avec isset(). Il retourne son premier opérande s'il existe et n'est pas NULL; sinon il retourne son deuxième opérande.

Essentiellement, en utilisant l'opérateur coalescent, il vérifiera automatiquement null contrairement à l'opérateur ternaire.

3
répondu Script47 2016-01-03 19:44:59

Il semble qu'il y ait des avantages et des inconvénients à utiliser ?? ou ?:. Le pro à l'aide de ?: est qu'il évalue false et null et "" la même chose. Le con est qu'il signale un E_NOTICE si l'argument précédent est null. Avec ?? Le pro est qu'il n'y a pas E_NOTICE, mais le con est qu'il n'évalue pas false et null de la même manière. Dans mon expérience, j'ai vu des gens commencer à utiliser null et false de manière interchangeable, mais ils ont finalement recours à la modification de leur code pour être compatibles avec en utilisant null ou false, mais pas les deux. Une alternative est de créer une condition ternaire plus élaborée: (isset($something) or !$something) ? $something : $something_else.

Ce qui suit est un exemple de la différence d'utiliser l'opérateur ?? en utilisant à la fois null Et false:

$false = null;
$var = $false ?? "true";
echo $var . "---<br>";//returns: true---

$false = false;
$var = $false ?? "true";
echo $var . "---<br>"; //returns: ---

En développant l'opérateur ternaire cependant, nous pouvons faire en sorte qu'une chaîne "" fausse ou vide se comporte comme si elle était nulle sans lancer d'e_notice:

$false = null;
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: ---

$false = false;
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: ---

$false = "";
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: ---

$false = true;
$var = (isset($false) or !$false) ? $false : "true";
echo $var . "---<br>";//returns: 1---

Personnellement, je pense que ce serait vraiment bien si un futur rev de PHP en incluait un autre nouvel opérateur: :?, qui a remplacé la syntaxe ci-dessus. IE: // $var = $false :? "true"; cette syntaxe évaluerait null, false et "" également et ne lancerait pas un E_NOTICE...

3
répondu Damian Green 2017-07-09 02:28:02
class a
{
    public $a = 'aaa';
}

$a = new a();

echo $a->a;  // Writes 'aaa'
echo $a->b;  // Notice: Undefined property: a::$b

echo $a->a ?? '$a->a does not exists';  // Writes 'aaa'

// Does not throw an error although $a->b does not exist.
echo $a->b ?? '$a->b does not exist.';  // Writes $a->b does not exist.

// Does not throw an error although $a->b and also $a->b->c does not exist.
echo $a->b->c ?? '$a->b->c does not exist.';  // Writes $a->b->c does not exist.
1
répondu Čamo 2017-09-15 11:25:30

Null Coalescing operator effectue seulement deux tâches: il vérifie whether the variable is set et whether it is null. Regardez l'exemple suivant:

<?php
# case 1:
$greeting = 'Hola';
echo $greeting ?? 'Hi There'; # outputs: 'Hola'

# case 2:
$greeting = null;
echo $greeting ?? 'Hi There'; # outputs: 'Hi There'

# case 3:
unset($greeting);
echo $greeting ?? 'Hi There'; # outputs: 'Hi There'

L'exemple de code ci-dessus indique que Null Coalescing operator traite une variable non existante et une variable qui est définie sur NULL de la même manière.

Null Coalescing operator est une amélioration par rapport à la ternary operator. Jetez un oeil à l'extrait de code suivant comparant les deux:

<?php /* example: checking for the $_POST field that goes by the name of 'fullname'*/
# in ternary operator
echo "Welcome ", (isset($_POST['fullname']) && !is_null($_POST['fullname']) ? $_POST['fullname'] : 'Mr. Whosoever.'); # outputs: Welcome Mr. Whosoever.
# in null coalecing operator
echo "Welcome ", ($_POST['fullname'] ?? 'Mr. Whosoever.'); # outputs: Welcome Mr. Whosoever.

Donc, la différence entre les deux est que l'opérateur Null Coalescing operator est conçu pour gérer des variables non définies mieux que le ternary operator. Attendu que, le ternary operator est un raccourci pour if-else.

Null Coalescing operator n'est pas destiné à remplacer ternary operator, mais dans certains cas d'utilisation, comme dans l'exemple ci-dessus, il vous permet d'écrire du code propre avec moins de tracas.

Crédits: http://dwellupper.io/post/6/php7-null-coalescing-operator-usage-and-examples

0
répondu Pranav Rana 2017-11-14 02:27:39