Wie unterscheiden sich die Vergleichsoperatoren PHP-Gleichheit (== Doppelgleich) und Identität (=== Dreifachgleich)?


509

Was ist der Unterschied zwischen ==und ===?

  • Wie genau funktioniert der lose ==Vergleich?
  • Wie genau funktioniert der strenge ===Vergleich?

Was wären einige nützliche Beispiele?

Antworten:


633

Unterschied zwischen ==und===

Der Unterschied zwischen dem lose ==gleichen Operator und dem streng ===identischen Operator wird im Handbuch genau erläutert :

Vergleichsoperatoren

┌────────────────────────────────────────────────── ───────────────────────────────────┐
│ Beispiel │ Name │ Ergebnis │
├────────────────────────────────────────────────── ───────────────────────────────────┤
│ $ a == $ b │ Gleich │ WAHR, wenn $ a nach dem Jonglieren gleich $ b ist. │
│ $ a === $ b │ Identisch │ WAHR, wenn $ a gleich $ b ist und sie vom gleichen Typ sind. │
└────────────────────────────────────────────────── ───────────────────────────────────┘

Locker ==gleicher Vergleich

Wenn Sie den verwenden ==Operator oder einen anderen Vergleichsoperator , den losen Vergleich verwendet wie !=, <>oder ==haben Sie immer Blick auf dem Kontext etwas zu sehen, wo und warum umgewandelt etwas wird , zu verstehen , was los ist.

Regeln konvertieren

Typvergleichstabelle

Als Referenz und Beispiel sehen Sie die Vergleichstabelle im Handbuch :

Lose Vergleiche mit ==

┌────────────────────────────────────────────────── ┬────────────────────────────────────────────────── ┬───────┐
│ │ TRUE │ FALSE │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ array () │ "php" │ "" │
├────────────────────────────────────────────────── ┼────────────────────────────────────────────────── ┼───────┤
│ WAHR │ WAHR │ FALSCH │ WAHR │ FALSCH │ WAHR │ WAHR │ FALSCH │ WAHR │ FALSCH │ FALSCH │ WAHR │ FALSCH │
│ FALSE │ FALSE │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ TRUE │ FALSE │ TRUE │ TRUE │ FALSE │ TRUE │
│ 1 │ WAHR │ FALSCH │ WAHR │ FALSCH │ FALSCH │ WAHR │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ FALSCH │
│ 0 │ FALSE │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ TRUE │ FALSE │ TRUE │ FALSE │ TRUE │ TRUE │
│ -1 │ WAHR │ FALSCH │ FALSCH │ FALSCH │ WAHR │ FALSCH │ FALSCH │ WAHR │ FALSCH │ FALSCH │ FALSCH │ FALSCH │
│ "1" │ WAHR │ FALSCH │ WAHR │ FALSCH │ FALSCH │ WAHR │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ FALSCH │
│ "0" │ FALSE │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ "-1" │ WAHR │ FALSCH │ FALSCH │ FALSCH │ WAHR │ FALSCH │ FALSCH │ WAHR │ FALSCH │ FALSCH │ FALSCH │ FALSCH │
│ NULL │ FALSCH │ WAHR │ FALSCH │ WAHR │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ WAHR │ WAHR │ FALSCH │ WAHR │
│ array () │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ TRUE │ FALSE │ FALSE │
Ph "php" │ WAHR │ FALSCH │ FALSCH │ WAHR │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ WAHR │ FALSCH │
│ "" │ FALSE │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ TRUE │
└────────────────────────────────────────────────── ┴────────────────────────────────────────────────── ┴───────┘

Streng ===identischer Vergleich

Wenn Sie den ===Operator oder einen anderen Vergleichsoperator verwenden, der einen strengen Vergleich wie !==oder verwendet ===, können Sie immer sicher sein, dass sich die Typen nicht auf magische Weise ändern, da keine Konvertierung stattfindet. Bei einem strengen Vergleich müssen also Typ und Wert gleich sein, nicht nur der Wert.

Typvergleichstabelle

Als Referenz und Beispiel sehen Sie die Vergleichstabelle im Handbuch :

Strenge Vergleiche mit ===

┌────────────────────────────────────────────────── ┬────────────────────────────────────────────────── ┬───────┐
│ │ TRUE │ FALSE │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ array () │ "php" │ "" │
├────────────────────────────────────────────────── ┼────────────────────────────────────────────────── ┼───────┤
│ WAHR │ WAHR │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ FALSCH │ FALSCH │
│ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ 1 │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ 0 │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ -1 │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ "1" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
│ "0" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
-1 "-1" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │
│ NULL │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │
│ array () │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │
Ph "php" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │
│ "" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │
└────────────────────────────────────────────────── ┴────────────────────────────────────────────────── ┴───────┘

65
findet es sonst noch jemand seltsam, dass "000" == "0000"?
Nickf

36
Was mich immer überrascht ist, dass false == array () und false == 0 aber array ()! = 0, also false == array ()! = / == 0? das fühlt sich komisch für mich an.
Pim Jager

4
@Pim ... Fortsetzung: Betrachten Sie es so: Beim Casting zu einem BOOL muss jeder Wert nur auf eine von zwei Seiten fallen, trueoder false. Das ist einfach zu besetzen. Alle anderen Werte haben jedoch für praktisch alle Zwecke praktisch unbegrenzte Kombinationen. Ist "five" == 5? array(0) == 0? array(0,0,0) == 0? 0.0000000000000000000000000000000000000000000000000001 == array()?
Täuschung

12
@ Raithlin, vorsichtig mit Array. Triple Equals gibt falsefür verschiedene Arrays in Javascript, aber truefür PHP, solange ihre Werte gleich sind .
Pacerier

14
@ Raithlin, viele, viele weitere Fallstricke. In JavaScript: "000" != "00" , "000" == null, "000" == false, "0x0" == false, array() == 0, false != null, array() != null, false == "0x0", false == "000". In PHP ist es entgegengesetztes Verhalten: "000" == "00" , "000" != null, "000" != false, "0x0" != false, array() != 0, false == null, array() == null, false != "0x0", false != "000".
Pacerier

239

Der Operator == wechselt zwischen zwei verschiedenen Typen, wenn sie unterschiedlich sind, während der Operator === einen 'typsicheren Vergleich' durchführt. Dies bedeutet, dass nur dann true zurückgegeben wird, wenn beide Operanden denselben Typ und denselben Wert haben.

Beispiele:

1 === 1: true
1 == 1: true
1 === "1": false // 1 is an integer, "1" is a string
1 == "1": true // "1" gets casted to an integer, which is 1
"foo" === "foo": true // both operands are strings and have the same value

Warnung : Zwei Instanzen derselben Klasse mit gleichwertigen Mitgliedern stimmen NICHT mit dem ===Operator überein . Beispiel:

$a = new stdClass();
$a->foo = "bar";
$b = clone $a;
var_dump($a === $b); // bool(false)

3
Nitpick: === wird nur true zurückgeben, wenn beide Operanden vom gleichen Typ sind und die Werte gleich sind =)
gnud

1
@gnud Genau das hat er im Beispiel gezeigt. Wenn es nur die Typen vergleichen würde, würde es einfach als "Typvergleich" bezeichnet werden, nicht wahr?
Rob Stevenson-Leggett

3
Nachdem ich PHP 8 Jahre lang benutzt hatte, war ich gestern das erste Mal in einer Situation, in der ich ===

3
=== true, wenn sie gleich sind und denselben Typ haben. == true, wenn sie gleich sind. ! = wahr, wenn sie nicht gleich sind. ! == true, wenn sie entweder nicht gleich oder gleich sind, aber nicht vom gleichen Typ.
Jeremy C

1
Außerdem ist die Verwendung von === etwas schneller als ==, da der Wert nicht konvertiert werden muss, bevor überprüft wird, ob er gleich ist.
Clauziere

88

Ein Bild sagt mehr als tausend Worte:

PHP Double Equals ==Gleichheitstabelle:

Geben Sie hier die Bildbeschreibung ein

PHP Triple Equals ===Equality-Diagramm:

Geben Sie hier die Bildbeschreibung ein

Quellcode zum Erstellen dieser Bilder:

https://github.com/sentientmachine/php_equality_charts

Guru Meditation

Diejenigen, die ihre geistige Gesundheit bewahren möchten, lesen nicht weiter, weil nichts davon Sinn macht, außer zu sagen, dass das Wahnsinns-Fraktal von PHP so entworfen wurde.

  1. NAN != NANaber NAN == true.
  2. ==konvertiert linke und rechte Operanden in Zahlen, wenn links eine Zahl ist. Also 123 == "123foo", aber"123" != "123foo"
  3. Eine hexadezimale Zeichenfolge in Anführungszeichen ist gelegentlich ein Float und wird überraschend gegen Ihren Willen schweben, was zu einem Laufzeitfehler führt.

  4. ==ist nicht transitiv weil "0"== 0und 0 == ""aber"0" != ""

  5. PHP-Variablen, die noch nicht deklariert wurden, sind falsch, obwohl PHP undefinierte Variablen darstellen kann, ist diese Funktion deaktiviert ==.
  6. "6" == " 6",, "4.2" == "4.20"und "133" == "0133"aber 133 != 0133. Aber "0x10" == "16"und "1e3" == "1000"diese Überraschung String - Konvertierung zu Oktal Belichtung tritt sowohl ohne Ihre Anweisung oder Genehmigung, einen Laufzeitfehler verursacht.

  7. False == 0, "", []Und "0".

  8. Wenn Zahlen groß genug sind, sind sie == Unendlichkeit.

  9. Eine neue Klasse ist == bis 1.

  10. False ist der gefährlichste Wert, da False für die meisten anderen Variablen == ist und den Zweck meistens zunichte macht.

Hoffnung:

Wenn Sie PHP verwenden, sollten Sie den Operator "Double Equals" nicht verwenden. Wenn Sie Triple Equals verwenden, müssen Sie sich nur um NAN und Zahlen sorgen, die so nahe an der Unendlichkeit liegen, dass sie auf "unendlich" gesetzt werden. Mit Double Equals kann alles ==für irgendetwas überraschend sein oder oder kann gegen Ihren Willen und !=für etwas, von dem es offensichtlich gleich sein sollte , überrascht werden.

Überall, wo Sie ==in PHP verwenden, riecht es schlecht nach Code, da 85 Fehler darin enthalten sind, die durch implizite Casting-Regeln aufgedeckt werden, die von Millionen von Programmierern entwickelt wurden, die mit Brownian Motion programmieren.


Ist es wirklich eine gute Idee (auch sicher), immer Triple Equals zu verwenden?
Chazy Chaz

3
Ja, die transitive Eigenschaft von Triple Equals macht es sicherer und webbasierter.
Eric Leschinski

Wie kann eine Zahl nahe der Unendlichkeit sein? [explodierendes Gehirn-GIF]
Tim

40

In Bezug auf JavaScript:

Der Operator === funktioniert genauso wie der Operator ==, erfordert jedoch, dass seine Operanden nicht nur denselben Wert, sondern auch denselben Datentyp haben.

Im folgenden Beispiel wird beispielsweise "x und y sind gleich" angezeigt, nicht jedoch "x und y sind identisch".

var x = 4;
var y = '4';
if (x == y) {
    alert('x and y are equal');
}
if (x === y) {
    alert('x and y are identical');
}

Upvoted, da dies genau die gleiche Situation für PHP zu sein scheint.
David sagt, Monica

1
@ DavidThomas Es ist nicht genau das gleiche. Siehe stackoverflow.com/questions/12598407/…
xdazz

22

Eine Ergänzung zu den anderen Antworten zum Objektvergleich:

== vergleicht Objekte anhand des Objektnamens und ihrer Werte. Wenn zwei Objekte vom gleichen Typ sind und dieselben Elementwerte haben,$a == $b ergibt sich true.

=== vergleicht die interne Objekt-ID der Objekte. Auch wenn die Mitglieder gleich sind, $a !== $bwenn sie nicht genau das gleiche Objekt sind.

class TestClassA {
    public $a;
}

class TestClassB {
    public $a;
}

$a1 = new TestClassA();
$a2 = new TestClassA();
$b = new TestClassB();

$a1->a = 10;
$a2->a = 10;
$b->a = 10;

$a1 == $a1;
$a1 == $a2;  // Same members
$a1 != $b;   // Different classes

$a1 === $a1;
$a1 !== $a2; // Not the same object

12

In einfachsten Worten:

== prüft ob gleichwertig (nur Wert)

=== prüft, ob das gleiche (Wert && Typ)


Äquivalent gegen Gleiches ist: Eine Analogie

1 + 1 = 2 + 0 (äquivalent)

1 + 1 = 1 + 1 (gleich)


In PHP:

true == 1 (true - äquivalent im Wert)

true === 1 (false - nicht gleich im Wert && Typ)

  • true ist boolesch
  • 1 ist int

"=== prüft, ob derselbe (Wert && Typ)", nicht genau wahr. Zwei stdClass-Objekte haben den gleichen Typ von 'Objekt' (dh mit gettype ()), aber PHP sagt, dass sie zwei verschiedene Dinge sind, wenn Sie einen strengen Vergleich verwenden. Sehen Sie das .
MAChitgarha

8

Es geht nur um Datentypen. Nehmen Sie BOOLzum Beispiel ein (wahr oder falsch):

trueauch gleich 1und falseauch gleich0

Das ==kümmert sich beim Vergleich nicht um die Datentypen: Wenn Sie also eine Variable haben, die 1 ist (was auch sein könnte true):

$var=1;

Und dann vergleiche mit ==:

if ($var == true)
{
    echo"var is true";
}

Aber ist $vardas eigentlich nicht gleich true, oder? Es hat den int-Wert von1 stattdessen , was wiederum gleich true ist.

Mit === werden die Datentypen überprüft, um sicherzustellen, dass die beiden Variablen / Objekte / was auch immer denselben Typ verwenden.

Also wenn ich es täte

if ($var === true)
{
    echo "var is true";
}

Diese Bedingung wäre nicht wahr, wie $var !== truees nur ist== true (wenn Sie wissen, was ich meine).

Warum brauchst du das?

Einfach - werfen wir einen Blick auf eine der Funktionen von PHP: array_search() :

Die array_search()Funktion sucht einfach nach einem Wert in einem Array und gibt den Schlüssel des Elements zurück, in dem der Wert gefunden wurde. Wenn der Wert im Array nicht gefunden werden konnte, wird false zurückgegeben . Aber was ist, wenn Sie array_search()einen Wert für einen Wert erstellt haben, der im ersten Element des Arrays gespeichert wurde (das den Array-Schlüssel von haben würde 0)?array_search() Funktion würde 0 zurückgeben. Dies ist gleich false.

Also, wenn du es getan hast:

$arr = array("name");
if (array_search("name", $arr) == false)
{
    // This would return 0 (the key of the element the val was found
    // in), but because we're using ==, we'll think the function
    // actually returned false...when it didn't.
}

Sehen Sie also, wie dies jetzt ein Problem sein könnte?

Die meisten Leute verwenden nicht, == falsewenn sie prüfen, ob eine Funktion false zurückgibt. Stattdessen verwenden sie die !. Aber eigentlich ist dies genau das gleiche wie bei der Verwendung ==false. Wenn Sie also Folgendes getan haben:

$arr = array("name");
if (!array_search("name", $arr)) // This is the same as doing (array_search("name", $arr) == false)

Für solche Dinge würden Sie ===stattdessen das verwenden, damit der Datentyp überprüft wird.


8

Ein Beispiel ist, dass ein Datenbankattribut null oder "" sein kann:

$attributeFromArray = "";
if ($attributeFromArray ==  ""){}  //true
if ($attributeFromArray === ""){}  //true
if ($attributeFromArray ==  null){}  //true
if ($attributeFromArray === null){}  //false

$attributeFromArray = null;
if ($attributeFromArray ==  ""){}  //true
if ($attributeFromArray === ""){}  //false
if ($attributeFromArray ==  null){}  //true
if ($attributeFromArray === null){}  //true

7

php == ist ein Vergleichsoperator, der den Wert der Variablen vergleicht. Aber === vergleicht den Wert und den Datentyp.

Zum Beispiel,

<?php 
  $var1 = 10;
  $var2 = '10';

  if($var1 == $var2) {
    echo 'Variables are equal';
  } else {
    echo 'Variables are not equal';
  }
?>

In diesem Fall lautet die Ausgabe "Variablen sind gleich", obwohl ihre Datentypen unterschiedlich sind.

Wenn wir jedoch === anstelle von == verwenden, lautet die Ausgabe 'Variablen sind nicht gleich'. Das PHP vergleicht zuerst den Wert der Variablen und dann den Datentyp. Hier sind die Werte gleich, aber die Datentypen sind unterschiedlich.


6

Gegeben x = 5

1) Operator: == ist "gleich". x == 8ist falsch
2) Operator: === ist "genau gleich" (Wert und Typ) x === 5ist wahr, x === "5"ist falsch


3
$a = 5;   // 5 as an integer

var_dump($a == 5);       // compare value; return true
var_dump($a == '5');     // compare value (ignore type); return true
var_dump($a === 5);      // compare type/value (integer vs. integer); return true
var_dump($a === '5');    // compare type/value (integer vs. string); return false

Sei aber vorsichtig. Hier ist ein berüchtigtes Problem.

// 'test' is found at position 0, which is interpreted as the boolean 'false'
if (strpos('testing', 'test')) {
    // code...
}

vs.

// true, as strict comparison was made (0 !== false)
if (strpos('testing', 'test') !== false) {
    // code...
}

3

Kurz gesagt, === funktioniert genauso wie == in den meisten anderen Programmiersprachen.

Mit PHP können Sie Vergleiche anstellen, die nicht wirklich sinnvoll sind. Beispiel:

$y = "wauv";
$x = false;
if ($x == $y)
    ...

Während dies einige interessante "Verknüpfungen" zulässt, sollten Sie aufpassen, da eine Funktion, die etwas zurückgibt, das sie nicht zurückgeben sollte (wie "Fehler" anstelle einer Zahl), nicht abgefangen wird und Sie sich fragen, was passiert ist.

In PHP vergleicht == Werte und führt bei Bedarf eine Typkonvertierung durch (z. B. wird die Zeichenfolge "12343sdfjskfjds" in einem ganzzahligen Vergleich zu "12343"). === vergleicht den Wert AND type und gibt false zurück, wenn der Typ nicht identisch ist.

Wenn Sie im PHP-Handbuch nachsehen, werden Sie feststellen, dass viele Funktionen "false" zurückgeben, wenn die Funktion fehlschlägt. In einem erfolgreichen Szenario geben sie jedoch möglicherweise 0 zurück. Aus diesem Grund empfehlen sie, "if (function ()! ==" auszuführen false) "um Fehler zu vermeiden.


1
Es sollte beachtet werden, dass zusätzlich zu diesen "Verknüpfungen" bekannt ist, dass das abnormale Verhalten des Operators == Sicherheitslücken öffnet, beispielsweise ein beliebtes PHP-Forum, in dem es möglich war, den Hash-Wert des Cookies-Passworts auf true zu setzen und dies zu umgehen die if (databaseBash == cookiehash) Validierung.
David

3

Einige Beispiele

var_dump(5 == 5);    // True
var_dump(5 == "5");  // True because == checks only same value not type
var_dump(5 === 5);   // True
var_dump(5 === "5"); // False because value are same but data type are different.

PS

== Vergleicht nur den Wert, es kümmert sich nicht um die Datentypen

vs.

=== Vergleicht die Werte und Datentypen


Was ist das Problem mit dieser Antwort?
Mohit Tanwani

2

Sie würden === verwenden, um zu testen, ob eine Funktion oder Variable falsch ist, anstatt nur falsch zu sein (Null oder eine leere Zeichenfolge).

$needle = 'a';
$haystack = 'abc';
$pos = strpos($haystack, $needle);
if ($pos === false) {
    echo $needle . ' was not found in ' . $haystack;
} else {
    echo $needle . ' was found in ' . $haystack . ' at location ' . $pos;
}

In diesem Fall würde strpos 0 zurückgeben, was im Test false entspricht

if ($pos == false)

oder

if (!$pos)

das ist nicht was du hier willst.


2

Nehmen Sie zum Beispiel die fwrite()Funktion in PHP an, wenn Sie eine über die andere verwenden möchten.

Diese Funktion schreibt Inhalte in einen Dateistream. Laut PHP " fwrite()gibt die Anzahl der geschriebenen Bytes oder FALSE bei einem Fehler zurück." Wenn Sie testen möchten, ob der Funktionsaufruf erfolgreich war, ist diese Methode fehlerhaft:

if (!fwrite(stuff))
{
    log('error!');
}

Es kann Null zurückgeben (und wird als erfolgreich angesehen), und Ihr Zustand wird immer noch ausgelöst. Der richtige Weg wäre:

if (fwrite(stuff) === FALSE)
{
    log('error!');
}

2

PHP ist eine lose getippte Sprache. Die Verwendung des Double-Equal-Operators ermöglicht eine lose Überprüfung einer Variablen.

Das lose Überprüfen eines Werts würde es ermöglichen, dass einige ähnliche, aber nicht gleiche Werte gleich sind:

  • ''
  • Null
  • falsch
  • 0

Alle diese Werte würden mit dem Operator double gleich gleich sein.


1

Variablen haben einen Typ und einen Wert.

  • $ var = "test" ist eine Zeichenfolge, die "test" enthält.
  • $ var2 = 24 ist eine Ganzzahl, deren Wert 24 ist.

Wenn Sie diese Variablen (in PHP) verwenden, haben Sie manchmal nicht den guten Typ. Zum Beispiel, wenn Sie dies tun

if ($var == 1) {... do something ...}

PHP muss $ var in Integer konvertieren ("to cast"). In diesem Fall ist "$ var == 1" wahr, da jede nicht leere Zeichenfolge in 1 umgewandelt wird.

Wenn Sie === verwenden, überprüfen Sie, ob der Wert AND THE TYPE gleich ist, sodass "$ var === 1" falsch ist.

Dies ist beispielsweise nützlich, wenn Sie eine Funktion haben, die false (bei Fehler) und 0 (Ergebnis) zurückgeben kann:

if(myFunction() == false) { ... error on myFunction ... }

Dieser Code ist falsch, als würde er myFunction()0 zurückgeben, er wird in false umgewandelt und Sie scheinen einen Fehler zu haben. Der richtige Code lautet:

if(myFunction() === false) { ... error on myFunction ... }

weil der Test ist, dass der Rückgabewert "ein Boolescher Wert und falsch ist" und nicht "in false umgewandelt werden kann".


In Bezug auf nicht leere Zeichenfolgen stimmt das eigentlich nicht. "a" == 0 ist WAHR.
Nickf

1

Der ===Operator soll die exakte Gleichheit der Inhalte vergleichen, während der ==Operator die semantische Gleichheit vergleichen würde. Insbesondere werden Zeichenfolgen zu Zahlen gezwungen.

Gleichheit ist ein großes Thema. Siehe den Wikipedia-Artikel zur Gleichstellung .


1
<?php

    /**
     * Comparison of two PHP objects                         ==     ===
     * Checks for
     * 1. References                                         yes    yes
     * 2. Instances with matching attributes and its values  yes    no
     * 3. Instances with different attributes                yes    no
     **/

    // There is no need to worry about comparing visibility of property or
    // method, because it will be the same whenever an object instance is
    // created, however visibility of an object can be modified during run
    // time using ReflectionClass()
    // http://php.net/manual/en/reflectionproperty.setaccessible.php
    //
    class Foo
    {
        public $foobar = 1;

        public function createNewProperty($name, $value)
        {
            $this->{$name} = $value;
        }
    }

    class Bar
    {
    }
    // 1. Object handles or references
    // Is an object a reference to itself or a clone or totally a different object?
    //
    //   ==  true   Name of two objects are same, for example, Foo() and Foo()
    //   ==  false  Name of two objects are different, for example, Foo() and Bar()
    //   === true   ID of two objects are same, for example, 1 and 1
    //   === false  ID of two objects are different, for example, 1 and 2

    echo "1. Object handles or references (both == and    ===) <br />";

    $bar = new Foo();    // New object Foo() created
    $bar2 = new Foo();   // New object Foo() created
    $baz = clone $bar;   // Object Foo() cloned
    $qux = $bar;         // Object Foo() referenced
    $norf = new Bar();   // New object Bar() created
    echo "bar";
    var_dump($bar);
    echo "baz";
    var_dump($baz);
    echo "qux";
    var_dump($qux);
    echo "bar2";
    var_dump($bar2);
    echo "norf";
    var_dump($norf);

    // Clone: == true and === false
    echo '$bar == $bar2';
    var_dump($bar == $bar2); // true

    echo '$bar === $bar2';
    var_dump($bar === $bar2); // false

    echo '$bar == $baz';
    var_dump($bar == $baz); // true

    echo '$bar === $baz';
    var_dump($bar === $baz); // false

    // Object reference: == true and === true
    echo '$bar == $qux';
    var_dump($bar == $qux); // true

    echo '$bar === $qux';
    var_dump($bar === $qux); // true

    // Two different objects: == false and === false
    echo '$bar == $norf';
    var_dump($bar == $norf); // false

    echo '$bar === $norf';
    var_dump($bar === $norf); // false

    // 2. Instances with matching attributes and its values (only ==).
    //    What happens when objects (even in cloned object) have same
    //    attributes but varying values?

    // $foobar value is different
    echo "2. Instances with matching attributes  and its values (only ==) <br />";

    $baz->foobar = 2;
    echo '$foobar' . " value is different <br />";
    echo '$bar->foobar = ' . $bar->foobar . "<br />";
    echo '$baz->foobar = ' . $baz->foobar . "<br />";
    echo '$bar == $baz';
    var_dump($bar == $baz); // false

    // $foobar's value is the same again
    $baz->foobar = 1;
    echo '$foobar' . " value is the same again <br />";
    echo '$bar->foobar is ' . $bar->foobar . "<br />";
    echo '$baz->foobar is ' . $baz->foobar . "<br />";
    echo '$bar == $baz';
    var_dump($bar == $baz); // true

    // Changing values of properties in $qux object will change the property
    // value of $bar and evaluates true always, because $qux = &$bar.
    $qux->foobar = 2;
    echo '$foobar value of both $qux and $bar is 2, because $qux = &$bar' . "<br />";
    echo '$qux->foobar is ' . $qux->foobar . "<br />";
    echo '$bar->foobar is ' . $bar->foobar . "<br />";
    echo '$bar == $qux';
    var_dump($bar == $qux); // true

    // 3. Instances with different attributes (only ==)
    //    What happens when objects have different attributes even though
    //    one of the attributes has same value?
    echo "3. Instances with different attributes (only ==) <br />";

    // Dynamically create a property with the name in $name and value
    // in $value for baz object
    $name = 'newproperty';
    $value = null;
    $baz->createNewProperty($name, $value);
    echo '$baz->newproperty is ' . $baz->{$name};
    var_dump($baz);

    $baz->foobar = 2;
    echo '$foobar' . " value is same again <br />";
    echo '$bar->foobar is ' . $bar->foobar . "<br />";
    echo '$baz->foobar is ' . $baz->foobar . "<br />";
    echo '$bar == $baz';
    var_dump($bar == $baz); // false
    var_dump($bar);
    var_dump($baz);
?>

1

Alle bisherigen Antworten ignorieren ein gefährliches Problem mit ===. Nebenbei wurde angemerkt, aber nicht betont, dass Integer und Double unterschiedliche Typen sind, also der folgende Code:

$n = 1000;
$d = $n + 0.0e0;
echo '<br/>'. ( ($n ==  $d)?'equal' :'not equal' );
echo '<br/>'. ( ($n === $d)?'equal' :'not equal' );

gibt:

 equal
 not equal

Beachten Sie, dass dies KEIN Fall eines "Rundungsfehlers" ist. Die beiden Zahlen sind bis zum letzten Bit genau gleich, haben jedoch unterschiedliche Typen.

Dies ist ein unangenehmes Problem, da ein Programm mit === jahrelang problemlos ausgeführt werden kann, wenn alle Zahlen klein genug sind (wobei "klein genug" von der Hardware und dem Betriebssystem abhängt, auf dem Sie ausgeführt werden). Wenn jedoch eine Ganzzahl zufällig groß genug ist, um in ein Double umgewandelt zu werden, wird ihr Typ "für immer" geändert, obwohl eine nachfolgende Operation oder viele Operationen sie möglicherweise auf eine kleine Ganzzahl zurückführen. Und es wird schlimmer. Es kann sich ausbreiten - Doppelinfektionen können nacheinander auf alles übertragen werden, was es berührt.

In der realen Welt ist dies wahrscheinlich ein Problem bei Programmen, die beispielsweise Daten über das Jahr 2038 hinaus verarbeiten. Zu diesem Zeitpunkt benötigen UNIX-Zeitstempel (Anzahl der Sekunden seit 1970-01-01 00:00:00 UTC) mehr als 32 Bit, sodass ihre Darstellung auf einigen Systemen "magisch" auf "doppelt" umgeschaltet wird. Wenn Sie also die Differenz zwischen zwei Malen berechnen, erhalten Sie möglicherweise einige Sekunden, jedoch als Doppel und nicht als ganzzahliges Ergebnis, das im Jahr 2017 auftritt.

Ich denke, das ist viel schlimmer als die Umrechnung zwischen Zeichenfolgen und Zahlen, weil es subtil ist. Ich finde es einfach zu verfolgen, was eine Zeichenfolge und was eine Zahl ist, aber die Anzahl der Bits in einer Zahl zu verfolgen, ist mir ein Rätsel.

In den obigen Antworten gibt es also einige nette Tabellen, aber keine Unterscheidung zwischen 1 (als Ganzzahl) und 1 (subtiles Doppel) und 1,0 (offensichtliches Doppel). Außerdem ist der Rat, den Sie immer === und niemals == verwenden sollten, nicht großartig, da === manchmal fehlschlägt, wenn == ordnungsgemäß funktioniert. Auch JavaScript ist in dieser Hinsicht nicht gleichwertig, da es nur einen Zahlentyp hat (intern kann es unterschiedliche bitweise Darstellungen haben, aber es verursacht keine Probleme für ===).

Mein Rat - benutze keine. Sie müssen Ihre eigene Vergleichsfunktion schreiben, um dieses Durcheinander wirklich zu beheben.


0

Es gibt zwei Unterschiede zwischen ==und ===in PHP-Arrays und -Objekten, die ich hier nicht erwähnt habe. zwei Arrays mit unterschiedlichen Schlüsselsorten und Objekten.

Zwei Arrays mit unterschiedlichen Schlüsselsorten

Wenn Sie ein Array mit einer Schlüsselsortierung und ein anderes Array mit einer anderen Schlüsselsortierung haben, sind diese streng unterschiedlich (dh verwenden ===). Dies kann dazu führen, dass Sie ein Array nach Schlüsseln sortieren und versuchen, das sortierte Array mit dem ursprünglichen Array zu vergleichen.

Betrachten Sie beispielsweise ein leeres Array. Zunächst versuchen wir, einige neue Indizes ohne spezielle Sortierung in das Array zu verschieben. Ein gutes Beispiel wäre ein Array mit Zeichenfolgen als Schlüssel. Nun tief in ein Beispiel:

// Define an array
$arr = [];

// Adding unsorted keys
$arr["I"] = "we";
$arr["you"] = "you";
$arr["he"] = "they";

Jetzt haben wir ein Array mit nicht sortierten Schlüsseln (z. B. "er" kam nach "Ihnen"). Betrachten Sie dasselbe Array, aber wir haben seine Schlüssel alphabetisch sortiert:

// Declare array
$alphabetArr = [];

// Adding alphabetical-sorted keys
$alphabetArr["I"] = "we";
$alphabetArr["he"] = "they";
$alphabetArr["you"] = "you";

Tipp : Sie können ein Array mit der Funktion ksort () nach Schlüsseln sortieren .

Jetzt haben Sie ein anderes Array mit einer anderen Schlüsselsortierung als das erste. Also werden wir sie vergleichen:

$arr == $alphabetArr; // true
$arr === $alphabetArr; // false

Hinweis : Es mag offensichtlich sein, aber der Vergleich zweier verschiedener Arrays mit einem strengen Vergleich führt immer zu Ergebnissen false. Zwei beliebige Arrays können jedoch gleich sein ===oder nicht.

Sie würden sagen: "Dieser Unterschied ist vernachlässigbar". Dann sage ich, es ist ein Unterschied und sollte in Betracht gezogen werden und kann jederzeit passieren. Wie oben erwähnt, ist das Sortieren von Schlüsseln in einem Array ein gutes Beispiel dafür.

Objekte

Beachten Sie, dass zwei verschiedene Objekte niemals streng gleich sind . Diese Beispiele würden helfen:

$stdClass1 = new stdClass();
$stdClass2 = new stdClass();
$clonedStdClass1 = clone $stdClass1;

// Comparing
$stdClass1 == $stdClass2; // true
$stdClass1 === $stdClass2; // false
$stdClass1 == $clonedStdClass1; // true
$stdClass1 === $clonedStdClass1; // false

Hinweis : Durch das Zuweisen eines Objekts zu einer anderen Variablen wird keine Kopie erstellt, sondern ein Verweis auf denselben Speicherort wie das Objekt erstellt. Siehe hier .

Hinweis : Ab PHP7 wurden anonyme Klassen hinzugefügt. Aus den Ergebnissen ergibt sich kein Unterschied zwischen new class {}und new stdClass()in den obigen Tests.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.