Odpowiedzi:
Kiedy twój pierwszy argument ma wartość NULL, są one w zasadzie takie same, z wyjątkiem tego, że koalescencja NULL nie daje E_NOTICE
wyniku, gdy masz niezdefiniowaną zmienną. Dokumenty dotyczące migracji do PHP 7.0 zawierają następujące informacje:
Operator zerowania koalescencji (??) został dodany jako cukier składniowy w typowym przypadku konieczności używania trójskładnika w połączeniu z isset (). Zwraca swój pierwszy operand, jeśli istnieje i nie ma wartości NULL; w przeciwnym razie zwraca drugi operand.
Oto przykładowy kod, który to pokazuje:
<?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";
Linie, które mają uwagę, to te, w których używam skróconego operatora trójskładnikowego, w przeciwieństwie do zerowego operatora koalescencyjnego. Jednak nawet z tym powiadomieniem PHP udzieli tej samej odpowiedzi.
Wykonaj kod: https://3v4l.org/McavC
Oczywiście zawsze zakłada się, że jest to pierwszy argument null
. Kiedy już nie będzie już zerowy, to kończysz się różnicami w tym, że ??
operator zawsze zwraca pierwszy argument, podczas gdy ?:
stenografia będzie tylko wtedy, gdy pierwszy argument byłby prawdziwy, i to zależy od tego, jak PHP wypisze rzeczy na boolean .
Więc:
$a = false ?? 'f'; // false
$b = false ?: 'g'; // 'g'
byłoby wtedy $a
równe false
i $b
równe 'g'
.
$b = []; var_dump($b['a']['b']['c'] ?? 'default');
lub z obiektami$b = new Foo; var_dump($b->a()->b()->c() ?? 'default');
$a = [];
. Zobacz: 3v4l.org/iCCa0
Uruchomiłem poniżej w interaktywnym trybie php ( php -a
na terminalu). Komentarz do każdej linii pokazuje wynik.
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"
??
:??
jest jak „brama”, która przepuszcza tylko NULL .NULL
. ??
że( !isset() || is_null() )
?:
?:
jest jak brama, która pozwala anything falsy
przepuszcza - w tymNULL
0
, empty string
, NULL
,false
, !isset()
, empty()
.. wszystko, co pachnie falsyecho ($x ? $x : false)
?:
wrzuci PHP NOTICE
na niezdefiniowany ( unset
lub!isset()
) zmienne??
i?:
...?:
kiedy
empty($x)
kontrole!empty($x) ? $x : $y
można skrócić$x ?: $y
if(!$x) { fn($x); } else { fn($y); }
można skrócić do fn(($x ?: $y))
??
kiedy
!isset() || is_null()
sprawdzenie$object = $object ?? new objClassName();
Operator trójskładnikowy można ustawiać w stos ...
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
Źródło i informacje o tym kodzie
Jest to w zasadzie sekwencja:
if( truthy ) {}
else if(truthy ) {}
else if(truthy ) {}
..
else {}
Operator zerowy może być ustawiany w stos ...
$v = $x ?? $y ?? $z;
Jest to sekwencja:
if(!isset($x) || is_null($x) ) {}
else if(!isset($y) || is_null($y) ) {}
else {}
Stosując stosy, mogę skrócić to:
if(!isset($_GET['name'])){
if($user_name){
$name = $user_name;
}else {
$name = 'anonymous';
}
} else {
$name = $_GET['name'];
}
Do tego:
$name = $_GET['name'] ?? $user_name ?: 'anonymous';
Fajnie, prawda? :-)
Jeśli użyjesz skrótu trójskładnikowego operatora w ten sposób, spowoduje to powiadomienie, jeśli $_GET['username']
nie zostanie ustawione:
$val = $_GET['username'] ?: 'default';
Zamiast tego musisz zrobić coś takiego:
$val = isset($_GET['username']) ? $_GET['username'] : 'default';
Operator zerowy koalescencyjny jest równoznaczne z powyższym stwierdzeniem, i powróci „default”, jeśli $_GET['username']
nie jest ustawiona lub jest null
:
$val = $_GET['username'] ?? 'default';
Zauważ, że nie sprawdza prawdziwości . Sprawdza tylko, czy jest ustawiony, a nie zerowy.
Możesz to również zrobić, a pierwsza zdefiniowana (ustawiona i nie null
) wartość zostanie zwrócona:
$val = $input1 ?? $input2 ?? $input3 ?? 'default';
Teraz jest to właściwy operator koalescencyjny.
Główną różnicą jest to
Wyrażenie operatora trójskładnikowegoexpr1 ?: expr3
zwraca wartość, expr1
jeśli jest expr1
przetwarzane,
TRUE
ale z drugiej strony wyrażenie operatora zerowego koalescencji(expr1) ?? (expr2)
ocenia, expr1
jeśli nieexpr1
jest NULL
Operator trójskładnikowy wysyła expr1 ?: expr3
powiadomienie, jeśli wartość po lewej stronie (expr1)
nie istnieje, ale z drugiej strony zerowy operator koalescencyjny (expr1) ?? (expr2)
W szczególności nie wysyła powiadomienia, jeśli wartość po lewej stronie (expr1)
nie istnieje, podobnie jak isset()
.
TernaryOperator pozostaje asocjacyjny
((true ? 'true' : false) ? 't' : 'f');
Operator zerowego koalescencji ma rację asocjacji
($a ?? ($b ?? $c));
Teraz wyjaśnijmy różnicę między przykładami:
Operator trójskładnikowy (?:)
$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);
Zerowy operator koalescencyjny (??)
$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);
Oto tabela wyjaśniająca różnicę i podobieństwo między '??'
i?:
Uwaga specjalna: operator koalescencji zerowej i operator trójskładnikowy jest wyrażeniem, które nie ocenia wartości zmiennej, lecz wynik wyrażenia. Jest to ważne, aby wiedzieć, czy chcesz zwrócić zmienną przez odwołanie. Instrukcja zwraca $ foo ?? bar $; i zwróci $ var == 42? $ a: $ b; dlatego funkcja powrotu przez odniesienie nie będzie działać i zostanie wyświetlone ostrzeżenie.
Oba zachowują się inaczej, jeśli chodzi o dynamiczne przetwarzanie danych.
Jeśli zmienna jest pusta (''), koalescencja zerowa potraktuje zmienną jako prawdziwą, ale skrócony operator potrójny nie. I o tym należy pamiętać.
$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';
A wynik:
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
.
Oba są skrótami dla dłuższych wyrażeń.
?:
jest skrótem od $a ? $a : $b
. To wyrażenie ma wartość $ a, jeśli $ a ma wartość PRAWDA .
??
jest skrótem od isset($a) ? $a : $b
. To wyrażenie będzie miało wartość $ a, jeśli $ a jest ustawione, a nie null.
Ich przypadki użycia pokrywają się, gdy $ a jest niezdefiniowany lub ma wartość null. Gdy $ a jest niezdefiniowane ??
, nie wygeneruje E_NOTICE, ale wyniki są takie same. Gdy $ a jest zerowe, wynik jest taki sam.
Dla początkujących:
Zerowy operator koalescencyjny (??)
Wszystko jest prawdą, z wyjątkiem null
wartości i niezdefiniowanych (zmienna / indeks tablicy / atrybuty obiektu)
dawny:
$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"
jest to w zasadzie sprawdzenie, czy zmienna (indeks tablicy, atrybut obiektu .. itd.) istnieje i nie istnieje null
. podobny doisset
funkcji
Skrócony operator trójskładnikowy (? :)
co fałszywe rzeczy ( false
, null
, 0
, pusty łańcuch) są przyjść jako fałszywe, ale jeśli jest to niezdefiniowane pochodzić również jako fałszywe, ale Notice
rzuci
dawny
$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: ..
Mam nadzieję że to pomoże
Przewiń w dół ten link i wyświetl sekcję, daje to porównawczy przykład, jak pokazano poniżej:
<?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';
?>
Nie zaleca się jednak łączenia łańcuchów operatorów, ponieważ utrudnia to zrozumienie kodu podczas jego późniejszego czytania.
Operator zerowania koalescencji (??) został dodany jako cukier składniowy w typowym przypadku konieczności używania trójskładnika w połączeniu z isset (). Zwraca swój pierwszy operand, jeśli istnieje i nie ma wartości NULL; w przeciwnym razie zwraca drugi operand.
Zasadniczo użycie operatora koalescencyjnego sprawi, że będzie ono automatycznie sprawdzać wartość zerową w przeciwieństwie do operatora trójskładnikowego.
a || b || c
wzorca w JS, z wyjątkiem tego, że PHP może być użyte do logów ( false || 2
w JS jest 2; false ?? 2
w PHP jest fałsz)
Pozostałe odpowiedzi sięgają głęboko i dają świetne wyjaśnienia. Dla tych, którzy szukają szybkiej odpowiedzi,
$a ?: 'fallback'
jest $a ? $a : 'fallback'
podczas
$a ?? 'fallback'
jest $a = isset($a) ? $a : 'fallback'
Główną różnicą byłoby, gdy lewy operator to:
0
, ''
, false
, []
, ...)$a =
powyższym rozszerzeniu nie powinno być ??
. $a ?? 'fallback'
nie ustawia ani nie zmienia wartości $ a. (Zwraca jedynie wartość).
Wygląda na to, że istnieją zalety i wady korzystania z jednego ??
lub ?:
. Zaletą użycia ?:
jest to, że ocenia fałsz, zero i to samo. Con polega na tym, że zgłasza E_NOTICE, jeśli poprzedzający argument jest pusty. Z ??
pro jest to, że nie ma E_NOTICE, ale wada polega na tym, że nie ocenia on fałszu i zeruje to samo. Z mojego doświadczenia wynika, że ludzie zaczęli używać zamiennie wartości NULL i FAŁSZ, ale w końcu uciekali się do modyfikacji kodu, aby był zgodny z użyciem wartości NULL lub FAŁSZ, ale nie obu. Alternatywą jest stworzenie bardziej rozbudowanego trójkowego warunku:(isset($something) or !$something) ? $something : $something_else
.
Poniżej znajduje się przykład różnicy używania ??
operatora przy użyciu zarówno wartości null, jak i false:
$false = null;
$var = $false ?? "true";
echo $var . "---<br>";//returns: true---
$false = false;
$var = $false ?? "true";
echo $var . "---<br>"; //returns: ---
Opracowując operator potrójny, możemy jednak zrobić fałszywy lub pusty ciąg „” zachowując się tak, jakby był zerowy bez rzucania 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---
Osobiście uważam, że byłoby naprawdę miło, gdyby w przyszłej wersji PHP pojawił się inny nowy operator: :?
który zastąpiłby powyższą składnię. tj.:
// $var = $false :? "true";
Ta składnia ocenia równe null, false i „” w równym stopniu i nie wyrzuca E_NOTICE ...
?? null ?:
sprawa jest niesamowita, dziękuję, panie. mądry facet.
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
wykonuje tylko dwa zadania: sprawdza whether the variable is set
i whether it is null
. Spójrz na następujący przykład:
<?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'
Powyższy przykład kodu stanowi, że Null Coalescing operator
traktuje nieistniejącą zmienną i zmienną ustawioną NULL
w ten sam sposób.
Null Coalescing operator
jest poprawą w stosunku do ternary operator
. Spójrz na następujący fragment kodu porównujący oba:
<?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.
Różnica między nimi polega na tym Null Coalescing operator
, że operator jest zaprojektowany tak, aby lepiej obsługiwać niezdefiniowane zmienne ternary operator
. Tymczasem ternary operator
jest to skrótif-else
.
Null Coalescing operator
nie ma na celu zastąpienia ternary operator
, ale w niektórych przypadkach użycia, takich jak w powyższym przykładzie, pozwala na pisanie czystego kodu bez większych problemów.
Kredyty: http://dwellupper.io/post/6/php7-null-coalescing-operator-usage-and-examples
isset($_POST['fullname'])
już sprawdza NULL
wartości - więc && !is_null($_POST['fullname'])
w pierwszym przykładzie i tak jest zbędny
Korzystając z superglobali, takich jak $ _GET lub $ _REQUEST, należy pamiętać, że mogą to być puste ciągi znaków. W tym szczególnym przypadku ten przykład
$username = $_GET['user'] ?? 'nobody';
zakończy się niepowodzeniem, ponieważ wartość $ username jest teraz pustym ciągiem.
Tak więc, używając $ _GET, a nawet $ _REQUEST, powinieneś użyć operatora trójskładnikowego w następujący sposób:
$username = (!empty($_GET['user'])?$_GET['user']:'nobody';
Teraz wartością $ username jest „nikt”, zgodnie z oczekiwaniami.