Risposte:
Quando il tuo primo argomento è nullo, sono sostanzialmente gli stessi tranne per il fatto che la coalescenza nulla non produrrà un E_NOTICE
quando hai una variabile indefinita. I documenti di migrazione di PHP 7.0 hanno questo da dire:
L'operatore null coalescing (??) è stato aggiunto come zucchero sintattico per il caso comune di necessità di utilizzare un ternario insieme a isset (). Restituisce il suo primo operando se esiste e non è NULL; altrimenti restituisce il suo secondo operando.
Ecco alcuni esempi di codice per dimostrarlo:
<?php
$a = null;
print $a ?? 'b'; // b
print "\n";
print $a ?: 'b'; // b
print "\n";
print $c ?? 'a'; // a
print "\n";
print $c ?: 'a'; // Notice: Undefined variable: c in /in/apAIb on line 14
print "\n";
$b = array('a' => null);
print $b['a'] ?? 'd'; // d
print "\n";
print $b['a'] ?: 'd'; // d
print "\n";
print $b['c'] ?? 'e'; // e
print "\n";
print $b['c'] ?: 'e'; // Notice: Undefined index: c in /in/apAIb on line 33
print "\n";
Le linee che hanno l'avviso sono quelle in cui sto usando l'operatore stenografico stenografico al contrario dell'operatore a coalescenza nulla. Tuttavia, anche con l'avviso, PHP restituirà la stessa risposta.
Eseguire il codice: https://3v4l.org/McavC
Naturalmente, questo presuppone sempre che il primo argomento sia null
. Una volta che non è più nullo, si ottengono differenze in quanto l' ??
operatore restituisce sempre il primo argomento mentre la ?:
scorciatoia lo farebbe solo se il primo argomento fosse veritiero, e ciò si basa sul modo in cui PHP scriverebbe le cose su un valore booleano .
Così:
$a = false ?? 'f'; // false
$b = false ?: 'g'; // 'g'
sarebbe quindi $a
uguale false
e $b
uguale a 'g'
.
$b = []; var_dump($b['a']['b']['c'] ?? 'default');
o con oggetti$b = new Foo; var_dump($b->a()->b()->c() ?? 'default');
$a = [];
. Vedi: 3v4l.org/iCCa0
Ho eseguito quanto segue in modalità interattiva php ( php -a
sul terminale). Il commento su ogni riga mostra il risultato.
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"
??
:??
è come un "gate" che lascia passare solo NULL .NULL
. ??
è lo stesso( !isset() || is_null() )
?:
?:
è come un cancello che anything falsy
attraversa - compresoNULL
0
, empty string
, NULL
, false
, !isset()
, empty()
.. tutto ciò che odora falsyecho ($x ? $x : false)
?:
genererà variabili PHP NOTICE
non definite ( unset
o !isset()
)??
e ?:
...?:
quando
empty($x)
controlli!empty($x) ? $x : $y
può essere accorciata$x ?: $y
if(!$x) { fn($x); } else { fn($y); }
può essere abbreviato in fn(($x ?: $y))
??
quando
!isset() || is_null()
controllo$object = $object ?? new objClassName();
L'operatore ternario può essere impilato ...
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
Fonte e credito per questo codice
Questa è sostanzialmente una sequenza di:
if( truthy ) {}
else if(truthy ) {}
else if(truthy ) {}
..
else {}
L'operatore Null Coalese può essere impilato ...
$v = $x ?? $y ?? $z;
Questa è una sequenza di:
if(!isset($x) || is_null($x) ) {}
else if(!isset($y) || is_null($y) ) {}
else {}
Usando lo stacking, posso accorciare questo:
if(!isset($_GET['name'])){
if($user_name){
$name = $user_name;
}else {
$name = 'anonymous';
}
} else {
$name = $_GET['name'];
}
A questa:
$name = $_GET['name'] ?? $user_name ?: 'anonymous';
Bene, vero? :-)
Se si utilizza l'operatore ternario di scelta rapida in questo modo, verrà generato un avviso se $_GET['username']
non è impostato:
$val = $_GET['username'] ?: 'default';
Quindi invece devi fare qualcosa del genere:
$val = isset($_GET['username']) ? $_GET['username'] : 'default';
L' operatore null coalescing è equivalente all'istruzione precedente e restituirà 'default' se $_GET['username']
non è impostato o è null
:
$val = $_GET['username'] ?? 'default';
Si noti che non verifica la verità . Controlla solo se è impostato e non è null.
Puoi anche farlo e il primo valore definito (impostato e non null
) verrà restituito:
$val = $input1 ?? $input2 ?? $input3 ?? 'default';
Questo è un vero operatore di coalescenza.
La differenza principale è quella
L' espressione dell'operatore ternarioexpr1 ?: expr3
ritorna expr1
se viene expr1
valutata
TRUE
ma, al contrario, l' espressione dell'operatore di coalescenza nulla(expr1) ?? (expr2)
valuta expr1
se non loexpr1
è NULL
L'operatore ternario expr1 ?: expr3
emette un avviso se il valore sul lato sinistro (expr1)
non esiste ma d'altro canto Null Coalescing Operator (expr1) ?? (expr2)
In particolare, non emette un avviso se il valore sul lato sinistro (expr1)
non esiste, proprio come isset()
.
TernaryOperator è associativo a sinistra
((true ? 'true' : false) ? 't' : 'f');
Null Coalescing Operator è il giusto associativo
($a ?? ($b ?? $c));
Ora spieghiamo la differenza tra l'esempio:
Operatore ternario (?:)
$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);
Operatore di coalescenza nulla (??)
$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);
Ecco la tabella che spiega la differenza e la somiglianza tra '??'
e?:
Nota speciale: l'operatore di coalescenza nulla e l'operatore ternario sono un'espressione e non valutano una variabile, ma il risultato di un'espressione. È importante sapere se si desidera restituire una variabile per riferimento. La dichiarazione restituisce $ foo ?? $ Bar; e restituire $ var == 42? $ a: $ b; in una funzione di ritorno per riferimento pertanto non funzionerà e verrà emesso un avviso.
Entrambi si comportano diversamente quando si tratta di gestione dinamica dei dati.
Se la variabile è vuota ('') la coalescenza nulla tratterà la variabile come vera, ma l'operatore sternale stenario no. E questo è qualcosa da tenere a mente.
$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';
E l'output:
1b
2b
2d
1f
Notice: Undefined variable: e in /in/ZBAa1 on line 21
2f
Link: https://3v4l.org/ZBAa1
It returns its first operand if it exists and is not NULL; otherwise it returns its second operand
.
Entrambi sono scorciatoie per espressioni più lunghe.
?:
è l'abbreviazione di $a ? $a : $b
. Questa espressione verrà valutata in $ a se $ a verrà valutata come TRUE .
??
è l'abbreviazione di isset($a) ? $a : $b
. Questa espressione verrà valutata in $ a se $ a è impostato e non è null.
I loro casi d'uso si sovrappongono quando $ a è indefinito o nullo. Quando $ a è indefinito ??
non produrrà un E_NOTICE, ma i risultati sono gli stessi. Quando $ a è null, il risultato è lo stesso.
Per i principianti:
Operatore a coalescenza nulla (??)
Tutto è vero tranne i null
valori e non definito (variabile / indice array / attributi oggetto)
ex:
$array = [];
$object = new stdClass();
var_export (false ?? 'second'); # false
var_export (true ?? 'second'); # true
var_export (null ?? 'second'); # 'second'
var_export ('' ?? 'second'); # ""
var_export ('some text' ?? 'second'); # "some text"
var_export (0 ?? 'second'); # 0
var_export ($undefinedVarible ?? 'second'); # "second"
var_export ($array['undefined_index'] ?? 'second'); # "second"
var_export ($object->undefinedAttribute ?? 'second'); # "second"
questo è fondamentalmente verificare che la variabile (indice dell'array, attributo oggetto ecc.) sia esistente e non null
. simile alla isset
funzione
Stenografia dell'operatore ternario (? :)
ogni cose false ( false
, null
, 0
, stringa vuota) sono venuti come false, ma se si tratta di un indefinito ma vengono anche come falso, ma Notice
getteranno
ex
$array = [];
$object = new stdClass();
var_export (false ?: 'second'); # "second"
var_export (true ?: 'second'); # true
var_export (null ?: 'second'); # "second"
var_export ('' ?: 'second'); # "second"
var_export ('some text' ?? 'second'); # "some text"
var_export (0 ?: 'second'); # "second"
var_export ($undefinedVarible ?: 'second'); # "second" Notice: Undefined variable: ..
var_export ($array['undefined_index'] ?: 'second'); # "second" Notice: Undefined index: ..
var_export ($object->undefinedAttribute ?: 'second'); # "Notice: Undefined index: ..
Spero che questo ti aiuti
Scorri verso il basso su questo link e visualizza la sezione, ti dà un esempio comparativo come mostrato di seguito:
<?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';
?>
Tuttavia, non è consigliabile incatenare gli operatori in quanto rende più difficile la comprensione del codice durante la lettura successiva.
L'operatore null coalescing (??) è stato aggiunto come zucchero sintattico per il caso comune di necessità di utilizzare un ternario insieme a isset (). Restituisce il suo primo operando se esiste e non è NULL; altrimenti restituisce il suo secondo operando.
In sostanza, l'uso dell'operatore coalescente lo farà controllare automaticamente per null a differenza dell'operatore ternario.
a || b || c
modello comune in JS, tranne per i PHP che possono essere usati per i booleani ( false || 2
in JS è 2; false ?? 2
in PHP è falso)
Le altre risposte vanno in profondità e danno grandi spiegazioni. Per coloro che cercano una risposta rapida,
$a ?: 'fallback'
è $a ? $a : 'fallback'
mentre
$a ?? 'fallback'
è $a = isset($a) ? $a : 'fallback'
La differenza principale sarebbe quando l'operatore di sinistra è:
0
, ''
, false
, []
, ...)$a =
nell'espansione sopra di ??
. $a ?? 'fallback'
non imposta o modifica il valore di $ a. (Restituisce semplicemente un valore).
Sembra che ci siano pro e contro nell'utilizzare ??
o ?:
. Il pro da usare ?:
è che valuta false e null e "" lo stesso. Il contro è che riporta un E_NOTICE se l'argomento precedente è nullo. Con ??
il pro è che non esiste E_NOTICE, ma il contro è che non valuta false e null lo stesso. Nella mia esperienza, ho visto persone iniziare a usare null e false in modo intercambiabile, ma alla fine ricorrono a modificare il loro codice per essere coerenti con l'uso di null o false, ma non entrambi. Un'alternativa è quella di creare una condizione ternario più elaborato: (isset($something) or !$something) ? $something : $something_else
.
Di seguito è riportato un esempio della differenza di utilizzo ??
dell'operatore utilizzando sia null che false:
$false = null;
$var = $false ?? "true";
echo $var . "---<br>";//returns: true---
$false = false;
$var = $false ?? "true";
echo $var . "---<br>"; //returns: ---
Elaborando l'operatore ternario, tuttavia, possiamo far sì che una stringa "" falsa o vuota si comporti come se fosse un valore nullo senza generare un 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---
Personalmente, penso che sarebbe davvero bello se un futuro rev di PHP includesse un altro nuovo operatore: :?
che ha sostituito la sintassi sopra. vale a dire:
// $var = $false :? "true";
quella sintassi valuterà null, false e "" allo stesso modo e non genererà un E_NOTICE ...
?? null ?:
cosa è davvero fantastica, grazie signor. ragazzo intelligente.
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.
Null Coalescing operator
esegue solo due compiti: controlla whether the variable is set
e whether it is null
. Dai un'occhiata al seguente esempio:
<?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'esempio di codice sopra riportato afferma che Null Coalescing operator
tratta una variabile inesistente e una variabile impostata allo NULL
stesso modo.
Null Coalescing operator
è un miglioramento rispetto al ternary operator
. Dai un'occhiata al seguente frammento di codice confrontando i due:
<?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.
Quindi, la differenza tra i due è che l' Null Coalescing operator
operatore è progettato per gestire variabili indefinite meglio di ternary operator
. Considerando che, ternary operator
è una scorciatoia per if-else
.
Null Coalescing operator
non è destinato a sostituire ternary operator
, ma in alcuni casi d'uso come nell'esempio precedente, consente di scrivere codice pulito con meno problemi.
Crediti: http://dwellupper.io/post/6/php7-null-coalescing-operator-usage-and-examples
isset($_POST['fullname'])
controlla già i NULL
valori - quindi il && !is_null($_POST['fullname'])
primo esempio è comunque ridondante
Quando usi i superglobal come $ _GET o $ _REQUEST dovresti essere consapevole che potrebbero essere una stringa vuota. In questo caso specale questo esempio
$username = $_GET['user'] ?? 'nobody';
fallirà perché il valore di $ username ora è una stringa vuota.
Quindi quando usi $ _GET o anche $ _REQUEST dovresti usare l'operatore ternario invece in questo modo:
$username = (!empty($_GET['user'])?$_GET['user']:'nobody';
Ora il valore di $ username è "none" come previsto.