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_NOTICEwyniku, 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 $arówne falsei $bró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 -ana 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 tymNULL0, empty string, NULL,false , !isset(), empty().. wszystko, co pachnie falsyecho ($x ? $x : false) ?:wrzuci PHP NOTICEna niezdefiniowany ( unsetlub!isset() ) zmienne??i?: ...?:kiedy
empty($x)kontrole!empty($x) ? $x : $ymoż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ść, expr1jeśli jest expr1przetwarzane,
TRUEale z drugiej strony wyrażenie operatora zerowego koalescencji(expr1) ?? (expr2)
ocenia, expr1jeś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 Noticerzuci
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 || cwzorca w JS, z wyjątkiem tego, że PHP może być użyte do logów ( false || 2w JS jest 2; false ?? 2w 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 operatorwykonuje tylko dwa zadania: sprawdza whether the variable is seti 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 operatortraktuje nieistniejącą zmienną i zmienną ustawioną NULLw ten sam sposób.
Null Coalescing operatorjest 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 operatorjest 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 NULLwartoś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.