Wie unterscheiden sich die Vergleichsoperatoren PHP-Gleichheit (== doppelt gleich) und Identität (=== dreifach gleich)?


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?



Answers


Unterschied zwischen == und ===

Der Unterschied zwischen dem locker == gleichen Operator und dem strikten === identischen Operator wird im Handbuch genau erklärt:

Vergleichsoperatoren

┌──────────┬───────────┬───────────────────────────────────────────────────────────┐
│ Example  │ Name      │ Result                                                    │
├──────────┼───────────┼───────────────────────────────────────────────────────────┤
│$a ==  $b │ Equal     │ TRUE if $a is equal to $b after type juggling.            │
│$a === $b │ Identical │ TRUE if $a is equal to $b, and they are of the same type. │
└──────────┴───────────┴───────────────────────────────────────────────────────────┘

Lose == Gleicher Vergleich

Wenn Sie den Operator == oder irgendeinen anderen Vergleichsoperator verwenden, der nur lose Vergleiche wie != , <> Oder == , müssen Sie immer den Kontext betrachten, um zu sehen, was, wo und warum etwas konvertiert wird, um zu verstehen, was es geht voran.

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" │  ""   │
├─────────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼─────────┼───────┼───────┤
│ TRUE    │ TRUE  │ FALSE │ TRUE  │ FALSE │ TRUE  │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE   │ TRUE  │ FALSE │
│ FALSE   │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ TRUE  │ TRUE    │ FALSE │ TRUE  │
│ 1       │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ 0       │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE   │ TRUE  │ TRUE  │
│ -1      │ TRUE  │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "1"     │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "0"     │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ "-1"    │ TRUE  │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE   │ FALSE │ FALSE │
│ NULL    │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ TRUE    │ FALSE │ TRUE  │
│ array() │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ TRUE    │ FALSE │ FALSE │
│ "php"   │ TRUE  │ FALSE │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ TRUE  │ FALSE │
│ ""      │ FALSE │ TRUE  │ FALSE │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE  │ FALSE   │ FALSE │ TRUE  │
└─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘

=== identischer Vergleich

Wenn Sie den Operator === oder einen anderen Vergleichsoperator verwenden, der strenge Vergleiche verwendet, wie !== oder === , dann können Sie immer sicher sein, dass die Typen sich nicht magisch ändern, weil es keine Konvertierung gibt. los. Beim 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 :

Strikte Vergleiche mit ===

┌─────────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬─────────┬───────┬───────┐
│         │ TRUE  │ FALSE │   1   │   0   │  -1   │  "1"  │  "0"  │ "-1"  │ NULL  │ array() │ "php" │  ""   │
├─────────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼─────────┼───────┼───────┤
│ TRUE    │ TRUE  │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE   │ FALSE │ FALSE │
│ 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"    │ 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 │
│ "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  │
└─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘



Der Operator == wirft zwischen zwei verschiedenen Typen um, wenn diese verschieden sind, während der Operator === einen 'typsicheren Vergleich' durchführt. Das heißt, es wird nur dann true zurückgegeben, wenn beide Operanden den gleichen Typ und den gleichen 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 der gleichen Klasse mit entsprechenden === stimmen NICHT mit dem Operator === . Beispiel:

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



In Bezug auf JavaScript:

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

Das Beispiel unten zeigt beispielsweise "x und y sind gleich", aber nicht "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');
}



Ein Bild sagt mehr als tausend Worte:

PHP Double Equals == Gleichheitsdiagramm:

PHP Triple Equals === Gleichheitsdiagramm:

Quellcode zum Erstellen dieser Bilder:

https://github.com/sentientmachine/php_equality_charts

Guru Meditation

Diejenigen, die ihren Verstand behalten wollen, lesen nicht weiter.

  1. '==' konvertiert linke und rechte Operanden in Zahlen, wenn möglich (123 == "123foo", aber "123"! = "123foo"
  2. Ein Hex-String in Anführungszeichen ist gelegentlich ein Float und wird gegen Ihren Willen darauf geworfen.
  3. == ist nicht transitiv, weil ("0" ist == bis 0, und 0 ist == bis "", aber "0"! = "")
  4. "6" == "6", "4.2" == "4.20" und "133" == "0133". Aber 133! = 0133, weil 0133 oktal ist. Aber "0x10" == "16" und "1e3" == "1000"
  5. PHP-Variablen, die noch nicht deklariert wurden, sind falsch.

  6. False ist gleich 0, Blankstring und leeres Array und "0".

  7. Wenn Zahlen groß genug sind, sind sie == Infinity.
  8. NAN ist nicht selbst, aber es ist wahr.

  9. Eine frische Klasse ist == bis 1.

  10. Falsch ist der gefährlichste Wert, weil False == für die meisten anderen Variablen gilt.

Hoffnung:

Wenn Sie PHP verwenden, sollten Sie den double equals -Operator nicht verwenden. Verwenden Sie immer triple equals.




Eine Ergänzung zu den anderen Antworten zum Objektvergleich:

== vergleicht Objekte mit dem Namen des Objekts und deren Werten. Wenn zwei Objekte vom gleichen Typ sind und dieselben $a == $b ergibt $a == $b true.

=== vergleicht die interne Objekt-ID der Objekte. Selbst wenn die Mitglieder gleich sind, $a !== $b wenn 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



In einfachsten Worten:

== prüft ob äquivalent (nur Wert)

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


Äquivalent vs. Same: Eine Analogie

1 + 1 = 2 + 0 (gleichwertig)

1 + 1 = 1 + 1 (gleich)


In PHP:

true == 1 (true - Wertäquivalent)

true === 1 (falsch - nicht gleich im Wert && type)

  • Wahr ist Boolesch
  • 1 ist int



Es geht nur um Datentypen. Nimm ein BOOL (wahr oder falsch) zum Beispiel:

true auch gleich 1 und false auch gleich 0

Das == kümmert sich nicht um die Datentypen beim Vergleich: Also, wenn Sie eine Variable hätten, die 1 ist (was auch true ):

$var=1;

Und dann mit dem == vergleichen:

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

Aber $var ist eigentlich nicht true , oder? Es hat stattdessen den int-Wert von 1 , der wiederum 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, da $var !== true es nur == true (wenn Sie wissen, was ich meine).

Warum brauchen Sie das?

Einfach - werfen wir einen Blick auf eine der PHP-Funktionen: 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 einen array_search() für einen Wert haben, der im ersten Element des Arrays gespeichert wurde (der den array_search() 0 ) .... die Funktion array_search() würde 0 zurückgeben ... gleich falsch ...

Wenn du es also tust:

$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.
}

Also, sehen Sie, wie dies jetzt ein Problem sein könnte?

Die meisten Leute verwenden nicht == false wenn sie überprüfen, ob eine Funktion false zurückgibt. Stattdessen nutzen sie das ! .. Aber tatsächlich ist dies genau das gleiche wie die Verwendung von ==false , also wenn Sie es taten:

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

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




Ein Beispiel dafür 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



Gegeben x = 5

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




$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 notorisches 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...
}



Kurz gesagt funktioniert === auf die gleiche Weise wie in den meisten anderen Programmiersprachen.

Mit PHP können Sie Vergleiche anstellen, die keinen Sinn ergeben. Beispiel:

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

Während dies einige interessante "Abkürzungen" erlaubt, sollten Sie aufpassen, da eine Funktion, die etwas zurückgibt, was sie nicht sollte (wie "Fehler" anstelle einer Zahl), nicht erwischt wird, und Sie werden sich fragen, was passiert ist.

In PHP vergleicht == die Werte und führt ggf. eine Typkonvertierung durch (z. B. wird die Zeichenkette "12343sdfjskfjds" in einem Ganzzahlvergleich zu "12343"). === vergleicht den Wert UND den Typ und gibt false zurück, wenn der Typ nicht derselbe ist.

Wenn Sie im PHP-Handbuch nachschauen, werden Sie feststellen, dass viele Funktionen "false" zurückgeben, wenn die Funktion fehlschlägt, aber in einem erfolgreichen Szenario möglicherweise 0 zurückgeben. Deshalb empfehlen sie "if (function ()! ==") falsch) "um Fehler zu vermeiden.




Nur wenige der 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 wird sich nicht um die Datentypen kümmern

vs.

=== Vergleicht die Werte und Datentypen




Sie würden === verwenden, um zu testen, ob eine Funktion oder Variable falsch ist und nicht nur falsch (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 gleich false wäre.

if ($pos == false)

oder

if (!$pos)

Das ist nicht was du hier willst.




fwrite() zum Beispiel die Funktion fwrite() in PHP, wenn Sie eins über das andere verwenden wollen.

Diese Funktion schreibt den Inhalt in einen Dateistream. Laut PHP gibt " fwrite() die Anzahl der geschriebenen Bytes zurück oder FALSE bei einem Fehler." 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 gilt als erfolgreich), und Ihre Bedingung wird trotzdem ausgelöst. Der richtige Weg wäre:

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



Variablen haben einen Typ und einen Wert.

  • $ var = "test" ist eine Zeichenkette, die "test" enthält
  • $ var2 = 24 ist eine ganze Zahl, deren Wert 24 ist.

Wenn Sie diese Variablen verwenden (in PHP), haben Sie manchmal keinen guten Typ. Zum Beispiel, wenn Sie das tun

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

PHP muss $ var in eine Ganzzahl konvertieren ("to cast"). In diesem Fall ist "$ var == 1" true, da jede nicht leere Zeichenfolge auf 1 gesetzt wird.

Wenn Sie === verwenden, prüfen Sie, ob der Wert UND DER TYP gleich sind, daher ist "$ var === 1" falsch.

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

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

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

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

weil der Test ist, dass der Rückgabewert "ein boolescher Wert ist und falsch ist" und "nicht auf falsch umgewandelt werden kann".




Der Operator === soll die genaue Inhaltsgleichheit vergleichen, während der Operator == die semantische Gleichheit vergleicht. Insbesondere wird es Strings zu Zahlen zwingen.

Gleichheit ist ein großes Thema. Siehe den Wikipedia-Artikel über Gleichheit .




<?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);
?>



PHP ist eine locker getippte Sprache. Die Verwendung des doppelten Gleichheitsoperators ermöglicht eine lose Überprüfung einer Variablen.

Wenn Sie einen Wert locker prüfen, können Sie einige ähnliche, aber nicht gleiche Werte gleichsetzen:

  • ''
  • Null
  • falsch
  • 0

Alle diese Werte würden mit dem double equal-Operator gleichgesetzt.




Alle Antworten ignorieren bisher ein gefährliches Problem mit ===. Es wurde nebenbei bemerkt, aber nicht betont, dass Integer und Double verschiedene Typen sind, also folgender 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 "Rundungsfehler" ist. Die beiden Zahlen sind bis auf das letzte Bit genau gleich, aber sie haben unterschiedliche Typen.

Dies ist ein unangenehmes Problem, da ein Programm, das === verwendet, jahrelang glücklich läuft, wenn alle Zahlen klein genug sind (wobei "klein genug" von der Hardware und dem Betriebssystem abhängt, auf dem Sie laufen). Wenn ein Integer jedoch zufällig groß genug ist, um in ein Double umgewandelt zu werden, wird sein Typ "forever" geändert, obwohl eine nachfolgende Operation oder viele Operationen ihn zu einer kleinen Ganzzahl im Wert zurückführen könnten. Und es wird schlimmer. Es kann sich ausbreiten - doppelte Infektion kann an alles weitergegeben werden, was es berührt, eine Berechnung nach der anderen.

In der realen Welt ist dies wahrscheinlich ein Problem in Programmen, die zum Beispiel Daten über das Jahr 2038 hinaus verarbeiten. Zu diesem Zeitpunkt werden UNIX-Zeitstempel (Anzahl der Sekunden seit 1970-01-01 00:00:00 UTC) mehr als 32 Bit benötigen, daher wird ihre Darstellung auf einigen Systemen "magisch" auf doppelt umschalten. Wenn Sie also die Differenz zwischen zwei Zeitpunkten berechnen, können Sie mit ein paar Sekunden enden, aber als Doppel- und nicht als ganzzahliges Ergebnis, das im Jahr 2017 auftritt.

Ich denke, das ist viel schlimmer als Konversionen zwischen Strings und Zahlen, weil es subtil ist. Ich finde es einfach, den Überblick zu behalten, was ein String ist und was eine Zahl ist, aber die Anzahl der Bits in einer Zahl zu verfolgen, ist mir schleierhaft.

Also, in den obigen Antworten gibt es einige nette Tabellen, aber keinen Unterschied zwischen 1 (als ganze Zahl) und 1 (subtiles Doppel) und 1.0 (offensichtliches Doppel). Auch Ratschläge, die Sie immer verwenden sollten === und nie == ist nicht groß, weil === manchmal scheitern wird, wo == ordnungsgemäß funktioniert. Außerdem ist JavaScript in dieser Hinsicht nicht äquivalent, da es nur einen Zahlentyp hat (intern kann es unterschiedliche bitweise Darstellungen haben, aber es verursacht keine Probleme für ===).

Mein Rat - verwenden Sie keines von beiden. Sie müssen Ihre eigene Vergleichsfunktion schreiben, um dieses Chaos wirklich zu beheben.