Jämförelse: Skillnad mellan sidversioner
Admin (diskussion | bidrag) |
Admin (diskussion | bidrag) |
||
(14 mellanliggande sidversioner av samma användare visas inte) | |||
Rad 32: | Rad 32: | ||
Före PHP 8.0.0, om en sträng jämfördes med ett nummer eller en numerisk sträng, konverterades strängen till ett nummer innan jämförelsen utfördes. Detta kan leda till överraskande resultat som kan ses med följande exempel: | Före PHP 8.0.0, om en sträng jämfördes med ett nummer eller en numerisk sträng, konverterades strängen till ett nummer innan jämförelsen utfördes. Detta kan leda till överraskande resultat som kan ses med följande exempel: | ||
<?php | <?php | ||
var_dump(0 == "a"); | var_dump(0 == "a"); | ||
var_dump("1" == "01"); | |||
var_dump("10" == "1e1"); | |||
var_dump(100 == "1e2"); | |||
switch ("a") { | |||
case 0: | case 0: | ||
echo "0"; | echo "0"; | ||
Rad 48: | Rad 46: | ||
break; | break; | ||
} | } | ||
? | ?> | ||
Utmatningen av ovanstående exempel i PHP 7:bool(true) | Utmatningen av ovanstående exempel i PHP 7: | ||
bool(true) | |||
bool(true) | bool(true) | ||
bool(true) | bool(true) | ||
bool(true) | |||
bool(true) | |||
0 | 0 | ||
Utmatningen av ovanstående exempel i PHP 8: | Utmatningen av ovanstående exempel i PHP 8: | ||
bool(false) | |||
bool(true) | bool(false) | ||
bool(true) | bool(true) | ||
bool(true) | bool(true) | ||
bool(true) | |||
a | a | ||
<?php | <?php | ||
// Heltal | // Heltal | ||
Rad 107: | Rad 106: | ||
?> | ?> | ||
För olika typer görs jämförelsen enligt följande tabell (i ordning). | |||
== Jämförelse med Olika Typer == | |||
Jämförelse baserad på olika typer av operanderna beskrivs i tabellen nedan, som visar hur olika datatyper hanteras när de jämförs i PHP. | |||
{| class="wikitable" | |||
! Typ av Operand 1 !! Typ av Operand 2 !! Resultat | |||
|- | |||
| null eller sträng || sträng || Konvertera null till "", numerisk eller lexikal jämförelse | |||
|- | |||
| bool eller null || något || Konvertera båda sidor till bool, false < true | |||
|- | |||
| objekt || objekt || Inbyggda klasser kan definiera sin egen jämförelse, olika klasser är ojämförbara, samma klass se Objektjämförelse | |||
|- | |||
| sträng, resurs, int eller float || sträng, resurs, int eller float || Översätt strängar och resurser till nummer, vanlig matematik | |||
|- | |||
| array || array || En array med färre medlemmar är mindre, om nyckel från operand 1 inte finns i operand 2 är arrayerna ojämförbara, annars - jämför värde för värde (se följande exempel) | |||
|- | |||
| objekt || något || objekt är alltid större | |||
|- | |||
| array || något || array är alltid större | |||
|} | |||
== Exempel == | |||
Exempel #1 Boolean/null jämförelse | Exempel #1 Boolean/null jämförelse | ||
<?php | <?php | ||
// Bool och null jämförs alltid som bool | // Bool och null jämförs alltid som bool | ||
var_dump(1 == TRUE); // TRUE - samma som (bool)1 == TRUE | var_dump(1 == TRUE); // TRUE - samma som (bool)1 == TRUE | ||
var_dump(0 == FALSE); // TRUE - samma som (bool)0 == FALSE | var_dump(0 == FALSE); // TRUE - samma som (bool)0 == FALSE | ||
var_dump(100 < TRUE); // FALSE - samma som (bool)100 < TRUE | var_dump(100 < TRUE); // FALSE - samma som (bool)100 < TRUE | ||
var_dump(-10 < FALSE);// FALSE - samma som (bool)-10 < FALSE | var_dump(-10 < FALSE);// FALSE - samma som (bool)-10 < FALSE | ||
var_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool)NULL < (bool)-100 är FALSE < TRUE | |||
var_dump(min(-100, -10, NULL, 10, 100)); | |||
// NULL - (bool)NULL < (bool)-100 är FALSE < TRUE | |||
?> | ?> | ||
Exempel #2 Transkription av standard array jämförelse | '''Exempel #2 Transkription av standard array jämförelse''' | ||
<?php | <?php | ||
// Arrayer jämförs så här med standard jämförelseoperatorer samt rymdskeppsoperatören. | // Arrayer jämförs så här med standard jämförelseoperatorer samt rymdskeppsoperatören. | ||
function standard_array_compare($op1, $op2) | function standard_array_compare($op1, $op2) | ||
Rad 155: | Rad 172: | ||
} | } | ||
return 0; // $op1 == $op2 | return 0; // $op1 == $op2 | ||
} | |||
?> | ?> | ||
== Varning == | == Varning == | ||
Jämförelse av flyttal | Jämförelse av flyttal | ||
På grund av det sätt som flyttal representeras internt bör du inte testa två flyttal för likhet. | På grund av det sätt som flyttal representeras internt bör du inte testa två flyttal för likhet. | ||
Se dokumentationen för flyttal för mer information. | Se dokumentationen för flyttal för mer information. | ||
Notera: Var medveten om att PHP:s typomvandling inte alltid är uppenbar när man jämför värden av olika typer, särskilt jämförelser mellan int och bool eller int och strängar. Det är därför generellt rådligt att använda === och !== jämförelser snarare än == och != i de flesta fall. | '''''Notera:''''' Var medveten om att PHP:s typomvandling inte alltid är uppenbar när man jämför värden av olika typer, särskilt jämförelser mellan int och bool eller int och strängar. Det är därför generellt rådligt att använda === och !== jämförelser snarare än == och != i de flesta fall. | ||
== Ojämförbara Värden == | == Ojämförbara Värden == | ||
Rad 182: | Rad 198: | ||
Exempel #3 Tilldela ett standardvärde | Exempel #3 Tilldela ett standardvärde | ||
<?php | |||
// Exempel på användning för: Ternäroperator | |||
$action = (empty($_POST['action'])) ? 'default' : $_POST['action']; | |||
// Ovanstående är identiskt med detta if/else-uttalande | |||
if (empty($_POST['action'])) { | |||
$action = 'default'; | |||
} else { | |||
$action = $_POST['action']; | |||
} | |||
?> | |||
Uttrycket (expr1) ? (expr2) : (expr3) utvärderas till expr2 om expr1 utvärderas till sant, och expr3 om expr1 utvärderas till falskt. | Uttrycket (expr1) ? (expr2) : (expr3) utvärderas till expr2 om expr1 utvärderas till sant, och expr3 om expr1 utvärderas till falskt. | ||
Det är möjligt att utelämna den mellersta delen av ternäroperatören. Uttrycket expr1 ?: expr3 utvärderas till resultatet av expr1 om expr1 utvärderas till sant, och annars expr3. expr1 utvärderas endast en gång i detta fall. | Det är möjligt att utelämna den mellersta delen av ternäroperatören. Uttrycket expr1 ?: expr3 utvärderas till resultatet av expr1 om expr1 utvärderas till sant, och annars expr3. expr1 utvärderas endast en gång i detta fall. | ||
'''Notera:''' | '''Notera:''' Observera att ternäroperatorn är ett uttryck, och att den inte utvärderas till en variabel, utan till resultatet av ett uttryck. Detta är viktigt att veta om du vill returnera en variabel med referens. Uttalandet return $var == 42 ? $a : $b; i en return-by-reference-funktion kommer därför inte att fungera och en varning utfärdas. | ||
Observera att ternäroperatorn är ett uttryck, och att den inte utvärderas till en variabel, utan till resultatet av ett uttryck. Detta är viktigt att veta om du vill returnera en variabel med referens. Uttalandet return $var == 42 ? $a : $b; i en return-by-reference-funktion kommer därför inte att fungera och en varning utfärdas. | |||
'''Notera:''' | '''Notera:''' | ||
Rad 209: | Rad 225: | ||
Exempel #4 Icke-uppenbart Ternärt Beteende | Exempel #4 Icke-uppenbart Ternärt Beteende | ||
<?php | |||
// vid första anblicken verkar följande skriva ut 'true' | // vid första anblicken verkar följande skriva ut 'true' | ||
echo (true ? 'true' : false ? 't' : 'f'); | |||
echo (true ? 'true' : false ? 't' : 'f'); | |||
// dock är den faktiska utmatningen av ovanstående 't' före PHP 8.0.0 | // dock är den faktiska utmatningen av ovanstående 't' före PHP 8.0.0 | ||
// detta är för att ternära uttryck är vänsterassociativa | |||
// följande är en mer uppenbar version av samma kod som ovan | // detta är för att ternära uttryck är vänsterassociativa | ||
// följande är en mer uppenbar version av samma kod som ovan | |||
echo ((true ? 'true' : false) ? 't' : 'f'); | echo ((true ? 'true' : false) ? 't' : 'f'); | ||
// här kan man se att det första uttrycket utvärderas till 'true', vilket | // här kan man se att det första uttrycket utvärderas till 'true', vilket | ||
// i sin tur utvärderas till (bool)true, och därmed returnerar den sanna grenen av | // i sin tur utvärderas till (bool)true, och därmed returnerar den sanna grenen av | ||
// det andra ternära uttrycket. | // det andra ternära uttrycket. | ||
?> | |||
? | |||
'''Notera:''' | '''Notera:''' | ||
Kedjning av korta ternärer (?:) är stabil och beter sig rimligt. Det kommer att utvärderas till det första argumentet som utvärderas till ett icke-falskt värde. Notera att odefinierade värden fortfarande kommer att orsaka en varning. | |||
Exempel #5 Kort-ternär kedjning | Exempel #5 Kort-ternär kedjning | ||
<?php | |||
echo 0 ?: 1 ?: 2 ?: 3, PHP_EOL; //1 | |||
echo 0 ?: 0 ?: 2 ?: 3, PHP_EOL; //2 | |||
echo 0 ?: 0 ?: 0 ?: 3, PHP_EOL; //3 | |||
?> | |||
== Nullsammanfogningsoperatorn == | == Nullsammanfogningsoperatorn == | ||
En annan användbar kortfattad operator är "??" (eller nullsammanfogningsoperatorn). | En annan användbar kortfattad operator är "??" (eller nullsammanfogningsoperatorn). | ||
Rad 243: | Rad 264: | ||
Exempel #6 Tilldela ett standardvärde | Exempel #6 Tilldela ett standardvärde | ||
<?php | |||
// Exempel på användning för: Null Coalesce Operator | |||
$action = $_POST['action'] ?? 'default'; | |||
// Ovanstående är identiskt med detta if/else-uttalande | |||
if (isset($_POST['action'])) { | |||
$action = $_POST['action']; | |||
} else { | |||
$action = 'default'; | |||
} | |||
?> | |||
Uttrycket (expr1) ?? (expr2) utvärderas till expr2 om expr1 är null, och expr1 annars. | Uttrycket (expr1) ?? (expr2) utvärderas till expr2 om expr1 är null, och expr1 annars. | ||
I synnerhet genererar denna operator inte ett meddelande eller en varning om värdet på vänster sida inte finns, precis som isset(). Detta är särskilt användbart för arraynycklar. | I synnerhet genererar denna operator inte ett meddelande eller en varning om värdet på vänster sida inte finns, precis som isset(). Detta är särskilt användbart för arraynycklar. | ||
Notera: Observera att nullsammanfogningsoperatorn är ett uttryck, och att den inte utvärderas till en variabel, utan till resultatet av ett uttryck. Detta är viktigt att veta om du vill returnera en variabel med referens. Uttalandet return $foo ?? $bar; i en return-by-reference-funktion kommer därför inte att fungera och en varning utfärdas. | '''''Notera:''' Observera att nullsammanfogningsoperatorn är ett uttryck, och att den inte utvärderas till en variabel, utan till resultatet av ett uttryck. Detta är viktigt att veta om du vill returnera en variabel med referens. Uttalandet return $foo ?? $bar; i en return-by-reference-funktion kommer därför inte att fungera och en varning utfärdas.'' | ||
Notera: | '''Notera:''' | ||
Nullsammanfogningsoperatorn har låg prioritet. Det innebär att om den blandas med andra operatorer (som strängkonkatenering eller aritmetiska operatorer) kommer parenteser sannolikt att krävas. | Nullsammanfogningsoperatorn har låg prioritet. Det innebär att om den blandas med andra operatorer (som strängkonkatenering eller aritmetiska operatorer) kommer parenteser sannolikt att krävas. | ||
<?php | |||
/ Väcker en varning att $name är odefinierad. | |||
print 'Mr. ' . $name ?? 'Anonymous'; | print 'Mr. ' . $name ?? 'Anonymous'; | ||
// Skriver ut "Mr. Anonymous" | |||
print 'Mr. ' . ($name ?? 'Anonymous'); | print 'Mr. ' . ($name ?? 'Anonymous'); | ||
?> | |||
'''Notera:''' | '''Notera:''' | ||
Observera att nullsammanfogningsoperatorn tillåter enkel nesting: | |||
Exempel #7 Nesting nullsammanfogningsoperatorn | Exempel #7 Nesting nullsammanfogningsoperatorn | ||
<?php | |||
$foo = null; | |||
$bar = null; | |||
$baz = 1; | |||
$qux = 2; | |||
echo $foo ?? $bar ?? $baz ?? $qux; // ger 1 | |||
?><BR> | |||
[[PHP]]<BR> | |||
[[Språkreferens]] | |||
[[PHP]] | |||
[[Språkreferens]] | |||
https://www.php.net/manual/en/language.operators.comparison.php | |||
[[Kategori:Php]] |
Nuvarande version från 17 augusti 2024 kl. 06.38
Jämförelseoperatorer
Jämförelseoperatorer, som namnet antyder, tillåter dig att jämföra två värden. Du kanske också är intresserad av att se typernas jämförelsetabeller, eftersom de visar exempel på olika typerelaterade jämförelser.
Jämförelseoperatorer
Exempel | Namn | Resultat |
---|---|---|
$a == $b | Lika | sant om $a är lika med $b efter typomvandling. |
$a === $b | Identisk | sant om $a är lika med $b, och de är av samma typ. |
$a != $b | Inte lika | sant om $a inte är lika med $b efter typomvandling. |
$a <> $b | Inte lika | sant om $a inte är lika med $b efter typomvandling. |
$a !== $b | Inte identisk | sant om $a inte är lika med $b, eller de är inte av samma typ. |
$a < $b | Mindre än | sant om $a strikt är mindre än $b. |
$a > $b | Större än | sant om $a strikt är större än $b. |
$a <= $b | Mindre än eller lika med | sant om $a är mindre än eller lika med $b. |
$a >= $b | Större än eller lika med | sant om $a är större än eller lika med $b. |
$a <=> $b | Rymdskepp | Ett heltal mindre än, lika med, eller större än noll när $a är mindre än, lika med, eller större än $b, respektive. |
Om båda operanderna är numeriska strängar, eller en operand är ett nummer och den andra är en numerisk sträng, då görs jämförelsen numeriskt. Dessa regler gäller också för switch-satsen. Typomvandling sker inte när jämförelsen är === eller !== eftersom detta innebär att jämföra både typ och värde.
Varning
Före PHP 8.0.0, om en sträng jämfördes med ett nummer eller en numerisk sträng, konverterades strängen till ett nummer innan jämförelsen utfördes. Detta kan leda till överraskande resultat som kan ses med följande exempel:
<?php var_dump(0 == "a"); var_dump("1" == "01"); var_dump("10" == "1e1"); var_dump(100 == "1e2");
switch ("a") { case 0:
echo "0"; break;
case "a":
echo "a"; break;
} ?> Utmatningen av ovanstående exempel i PHP 7:
bool(true) bool(true) bool(true) bool(true) 0 Utmatningen av ovanstående exempel i PHP 8:
bool(false) bool(true) bool(true) bool(true) a <?php // Heltal echo 1 <=> 1; // 0 echo 1 <=> 2; // -1 echo 2 <=> 1; // 1
// Flyttal echo 1.5 <=> 1.5; // 0 echo 1.5 <=> 2.5; // -1 echo 2.5 <=> 1.5; // 1
// Strängar echo "a" <=> "a"; // 0 echo "a" <=> "b"; // -1 echo "b" <=> "a"; // 1
echo "a" <=> "aa"; // -1 echo "zz" <=> "aa"; // 1
// Arrayer echo [] <=> []; // 0 echo [1, 2, 3] <=> [1, 2, 3]; // 0 echo [1, 2, 3] <=> []; // 1 echo [1, 2, 3] <=> [1, 2, 1]; // 1 echo [1, 2, 3] <=> [1, 2, 4]; // -1
// Objekt $a = (object) ["a" => "b"]; $b = (object) ["a" => "b"]; echo $a <=> $b; // 0
$a = (object) ["a" => "b"]; $b = (object) ["a" => "c"]; echo $a <=> $b; // -1
$a = (object) ["a" => "c"]; $b = (object) ["a" => "b"]; echo $a <=> $b; // 1
// inte bara värden jämförs; nycklar måste matcha $a = (object) ["a" => "b"]; $b = (object) ["b" => "b"]; echo $a <=> $b; // 1
?> För olika typer görs jämförelsen enligt följande tabell (i ordning).
Jämförelse med Olika Typer
Jämförelse baserad på olika typer av operanderna beskrivs i tabellen nedan, som visar hur olika datatyper hanteras när de jämförs i PHP.
Typ av Operand 1 | Typ av Operand 2 | Resultat |
---|---|---|
null eller sträng | sträng | Konvertera null till "", numerisk eller lexikal jämförelse |
bool eller null | något | Konvertera båda sidor till bool, false < true |
objekt | objekt | Inbyggda klasser kan definiera sin egen jämförelse, olika klasser är ojämförbara, samma klass se Objektjämförelse |
sträng, resurs, int eller float | sträng, resurs, int eller float | Översätt strängar och resurser till nummer, vanlig matematik |
array | array | En array med färre medlemmar är mindre, om nyckel från operand 1 inte finns i operand 2 är arrayerna ojämförbara, annars - jämför värde för värde (se följande exempel) |
objekt | något | objekt är alltid större |
array | något | array är alltid större |
Exempel
Exempel #1 Boolean/null jämförelse
<?php
// Bool och null jämförs alltid som bool
var_dump(1 == TRUE); // TRUE - samma som (bool)1 == TRUE
var_dump(0 == FALSE); // TRUE - samma som (bool)0 == FALSE
var_dump(100 < TRUE); // FALSE - samma som (bool)100 < TRUE var_dump(-10 < FALSE);// FALSE - samma som (bool)-10 < FALSE
var_dump(min(-100, -10, NULL, 10, 100));
// NULL - (bool)NULL < (bool)-100 är FALSE < TRUE
?>
Exempel #2 Transkription av standard array jämförelse
<?php
// Arrayer jämförs så här med standard jämförelseoperatorer samt rymdskeppsoperatören. function standard_array_compare($op1, $op2) {
if (count($op1) < count($op2)) { return -1; // $op1 < $op2 } elseif (count($op1) > count($op2)) { return 1; // $op1 > $op2 } foreach ($op1 as $key => $val) { if (!array_key_exists($key, $op2)) { return 1; } elseif ($val < $op2[$key]) { return -1; } elseif ($val > $op2[$key]) { return 1; } } return 0; // $op1 == $op2
}
?>
Varning
Jämförelse av flyttal
På grund av det sätt som flyttal representeras internt bör du inte testa två flyttal för likhet.
Se dokumentationen för flyttal för mer information.
Notera: Var medveten om att PHP:s typomvandling inte alltid är uppenbar när man jämför värden av olika typer, särskilt jämförelser mellan int och bool eller int och strängar. Det är därför generellt rådligt att använda === och !== jämförelser snarare än == och != i de flesta fall.
Ojämförbara Värden
Medan identitetsjämförelse (=== och !==) kan tillämpas på godtyckliga värden, bör de andra jämförelseoperatorerna endast tillämpas på jämförbara värden. Resultatet av att jämföra ojämförbara värden är odefinierat och bör inte förlitas på.
Se även
Ternäroperatorn
En annan villkorlig operator är "?:" (eller ternäroperator).
Exempel #3 Tilldela ett standardvärde
<?php
// Exempel på användning för: Ternäroperator
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
// Ovanstående är identiskt med detta if/else-uttalande if (empty($_POST['action'])) {
$action = 'default';
} else {
$action = $_POST['action'];
}
?>
Uttrycket (expr1) ? (expr2) : (expr3) utvärderas till expr2 om expr1 utvärderas till sant, och expr3 om expr1 utvärderas till falskt.
Det är möjligt att utelämna den mellersta delen av ternäroperatören. Uttrycket expr1 ?: expr3 utvärderas till resultatet av expr1 om expr1 utvärderas till sant, och annars expr3. expr1 utvärderas endast en gång i detta fall.
Notera: Observera att ternäroperatorn är ett uttryck, och att den inte utvärderas till en variabel, utan till resultatet av ett uttryck. Detta är viktigt att veta om du vill returnera en variabel med referens. Uttalandet return $var == 42 ? $a : $b; i en return-by-reference-funktion kommer därför inte att fungera och en varning utfärdas.
Notera:
Det rekommenderas att undvika "staplade" ternära uttryck. PHP:s beteende när man använder mer än en oparanteserad ternär operator inom ett enda uttryck är inte uppenbart jämfört med andra språk. Faktum är att före PHP 8.0.0 utvärderades ternära uttryck vänsterassociativt, istället för högerassociativt som i de flesta andra programmeringsspråk. Att förlita sig på vänsterassociativitet är föråldrat från och med PHP 7.4.0. Från och med PHP 8.0.0 är ternäroperatören icke-associativ.
Exempel #4 Icke-uppenbart Ternärt Beteende
<?php
// vid första anblicken verkar följande skriva ut 'true'
echo (true ? 'true' : false ? 't' : 'f');
// dock är den faktiska utmatningen av ovanstående 't' före PHP 8.0.0
// detta är för att ternära uttryck är vänsterassociativa
// följande är en mer uppenbar version av samma kod som ovan
echo ((true ? 'true' : false) ? 't' : 'f');
// här kan man se att det första uttrycket utvärderas till 'true', vilket
// i sin tur utvärderas till (bool)true, och därmed returnerar den sanna grenen av // det andra ternära uttrycket. ?>
Notera:
Kedjning av korta ternärer (?:) är stabil och beter sig rimligt. Det kommer att utvärderas till det första argumentet som utvärderas till ett icke-falskt värde. Notera att odefinierade värden fortfarande kommer att orsaka en varning.
Exempel #5 Kort-ternär kedjning
<?php
echo 0 ?: 1 ?: 2 ?: 3, PHP_EOL; //1
echo 0 ?: 0 ?: 2 ?: 3, PHP_EOL; //2 echo 0 ?: 0 ?: 0 ?: 3, PHP_EOL; //3
?>
Nullsammanfogningsoperatorn
En annan användbar kortfattad operator är "??" (eller nullsammanfogningsoperatorn).
Exempel #6 Tilldela ett standardvärde
<?php
// Exempel på användning för: Null Coalesce Operator
$action = $_POST['action'] ?? 'default';
// Ovanstående är identiskt med detta if/else-uttalande
if (isset($_POST['action'])) {
$action = $_POST['action'];
} else {
$action = 'default';
}
?>
Uttrycket (expr1) ?? (expr2) utvärderas till expr2 om expr1 är null, och expr1 annars. I synnerhet genererar denna operator inte ett meddelande eller en varning om värdet på vänster sida inte finns, precis som isset(). Detta är särskilt användbart för arraynycklar.
Notera: Observera att nullsammanfogningsoperatorn är ett uttryck, och att den inte utvärderas till en variabel, utan till resultatet av ett uttryck. Detta är viktigt att veta om du vill returnera en variabel med referens. Uttalandet return $foo ?? $bar; i en return-by-reference-funktion kommer därför inte att fungera och en varning utfärdas.
Notera:
Nullsammanfogningsoperatorn har låg prioritet. Det innebär att om den blandas med andra operatorer (som strängkonkatenering eller aritmetiska operatorer) kommer parenteser sannolikt att krävas.
<?php
/ Väcker en varning att $name är odefinierad. print 'Mr. ' . $name ?? 'Anonymous';
// Skriver ut "Mr. Anonymous" print 'Mr. ' . ($name ?? 'Anonymous');
?>
Notera:
Observera att nullsammanfogningsoperatorn tillåter enkel nesting:
Exempel #7 Nesting nullsammanfogningsoperatorn
<?php
$foo = null; $bar = null; $baz = 1; $qux = 2;
echo $foo ?? $bar ?? $baz ?? $qux; // ger 1
?>
PHP
Språkreferens
https://www.php.net/manual/en/language.operators.comparison.php