Jämförelse: Skillnad mellan sidversioner
Admin (diskussion | bidrag) |
Admin (diskussion | bidrag) |
||
Rad 50: | Rad 50: | ||
Utmatningen av ovanstående exempel i PHP 7: | Utmatningen av ovanstående exempel i PHP 7: | ||
bool(true) | bool(true)<BR> | ||
bool(true) | bool(true)<BR> | ||
bool(true) | bool(true)<BR> | ||
bool(true) | bool(true)<BR> | ||
0 | 0 | ||
Utmatningen av ovanstående exempel i PHP 8: | Utmatningen av ovanstående exempel i PHP 8: | ||
bool(false) | bool(false)<BR> | ||
bool(true) | bool(true)<BR> | ||
bool(true) | bool(true)<BR> | ||
bool(true) | bool(true)<BR> | ||
a | a | ||
<code> | |||
<?php | <?php | ||
// Heltal | // Heltal |
Versionen från 17 augusti 2024 kl. 06.16
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
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 anything Konvertera båda sidorna 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 Omvandla strängar och resurser till nummer, vanlig matematik
array array Array med färre medlemmar är mindre, om nyckel från operand 1 inte finns i operand 2 då är arrayerna ojämförbara, annars - jämför värde för värde (se följande exempel)
objekt anything objekt är alltid större
array anything 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
?>
Sida är en översättning ifrån https://www.php.net/manual/en/language.operators.comparison.php