Jämförelse: Skillnad mellan sidversioner

Från Wiki.linux.se
Hoppa till navigering Hoppa till sök
 
Rad 313: Rad 313:


echo $foo ?? $bar ?? $baz ?? $qux; // ger 1
echo $foo ?? $bar ?? $baz ?? $qux; // ger 1
?>
?><BR>
[[PHP]]<BR>
[[PHP]]<BR>
[[Språkreferens]]
[[Språkreferens]]

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