In cosa differiscono gli operatori di confronto PHP di uguaglianza (== doppio uguale) e identità (=== triplo uguale)?

StackOverflow https://stackoverflow.com/questions/80646

Domanda

Qual è la differenza tra == E ===?

  • Come funziona esattamente il liberamente == lavoro di confronto?
  • Come funziona esattamente il rigoroso === lavoro di confronto?

Quali potrebbero essere degli esempi utili?

È stato utile?

Soluzione

Differenza fra == E ===

La differenza tra liberamente == operatore uguale e rigoroso === l'operatore identico è spiegato esattamente nel Manuale:

Operatori di confronto

┌──────────┬───────────┬───────────────────────────────────────────────────────────┐
│ 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. │
└──────────┴───────────┴───────────────────────────────────────────────────────────┘

Liberamente == confronto paritario

Se stai utilizzando il == operatore o qualsiasi altro operatore di confronto che utilizza liberamente il confronto come !=, <> O ==, devi sempre guardare il contesto per vedere cosa, dove e perché qualcosa si converte per capire cosa sta succedendo.

Conversione delle regole

Tabella di confronto dei tipi

Come riferimento ed esempio puoi vedere la tabella comparativa nel file Manuale:

Confronti vaghi con ==

┌─────────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬─────────┬───────┬───────┐
│         │ 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  │
└─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘

Rigoroso === confronto identico

Se stai utilizzando il === operatore o qualsiasi altro operatore di confronto che utilizza un confronto rigoroso come !== O ===, allora puoi sempre essere sicuro che i tipi non lo faranno magicamente cambiare, perché non ci sarà alcuna conversione in corso.Quindi, con un confronto rigoroso, il tipo e il valore devono essere gli stessi, non solo il valore.

Tabella di confronto dei tipi

Come riferimento ed esempio puoi vedere la tabella comparativa nel file Manuale:

Confronti severi con ===

┌─────────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬─────────┬───────┬───────┐
│         │ 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  │
└─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘

Altri suggerimenti

L'operatore == esegue il cast tra due tipi diversi se sono diversi, mentre l'operatore === esegue un "confronto typesafe".Ciò significa che restituirà vero solo se entrambi gli operandi hanno lo stesso tipo e lo stesso valore.

Esempi:

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

Avvertimento:due istanze della stessa classe con membri equivalenti NON corrispondono a === operatore.Esempio:

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

Un'immagine vale più di mille parole:

PHP doppio uguale == tabella di uguaglianza:

enter image description here

PHP triplo uguale === Grafico dell'uguaglianza:

enter image description here

Codice sorgente per creare queste immagini:

https://github.com/sentientmachine/php_equality_charts

Meditazione del Guru

Coloro che desiderano mantenere la propria sanità mentale, non leggano oltre perché nulla di tutto ciò avrà alcun senso, tranne dire che questo è il modo in cui è stato progettato il frattale della follia di PHP.

  1. NAN != NAN Ma NAN == true.
  2. == convertirà gli operandi sinistro e destro in numeri se left è un numero.COSÌ 123 == "123foo", Ma "123" != "123foo"
  3. Una stringa esadecimale tra virgolette è occasionalmente un float e verrà lanciata a sorpresa in float contro la tua volontà, causando un errore di runtime.

  4. == non è transitivo perché "0"== 0, E 0 == "" Ma "0" != ""

  5. Le variabili PHP che non sono state ancora dichiarate sono false, anche se PHP ha un modo per rappresentare variabili non definite, tale funzionalità è disabilitata con ==.
  6. "6" == " 6", "4.2" == "4.20", E "133" == "0133" Ma 133 != 0133.Ma "0x10" == "16" E "1e3" == "1000" esponendo che la conversione a sorpresa della stringa in ottale avverrà senza istruzioni o consenso, causando un errore di runtime.

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

  8. Quando i numeri sono abbastanza grandi sono == Infinito.

  9. Una nuova classe è == a 1.

  10. False è il valore più pericoloso perché False è == per la maggior parte delle altre variabili, vanificando per lo più il suo scopo.

Speranza:

Se stai usando PHP, non utilizzerai l'operatore doppio uguale perché se usi triplo uguale, gli unici casi limite di cui preoccuparti sono NAN e numeri così vicini all'infinito da essere convertiti all'infinito.Con il doppio uguale, tutto può essere una sorpresa == a qualsiasi cosa o, o può essere lanciato a sorpresa contro la tua volontà e != a qualcosa di cui dovrebbe ovviamente essere uguale.

Ovunque tu usi == in PHP ha un cattivo odore di codice a causa degli 85 bug in esso esposti da regole di casting implicite che sembrano progettate da milioni di programmatori che programmano secondo il movimento browniano.

Per quanto riguarda JavaScript:

L'operatore === funziona allo stesso modo dell'operatore ==, ma richiede che i suoi operandi abbiano non solo lo stesso valore, ma anche lo stesso tipo di dati.

Ad esempio, l'esempio seguente visualizzerà "xey sono uguali", ma non "xey sono identici".

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

Un'aggiunta alle altre risposte relative al confronto degli oggetti:

== confronta gli oggetti utilizzando il nome dell'oggetto e i relativi valori.Se due oggetti sono dello stesso tipo e hanno gli stessi valori membro, $a == $b restituisce vero.

=== confronta l'ID oggetto interno degli oggetti.Anche se i membri sono uguali, $a !== $b se non sono esattamente lo stesso oggetto.

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 termini più semplici:

== controlla se equivalente (solo valore)

=== controlla se il Stesso (valore && tipo)


Equivalente vs.Stesso:Un'analogia

1 + 1 = 2 + 0 (equivalente)

1 + 1 = 1 + 1 (Stesso)


Nel PHP:

vero == 1 (vero - equivalente in valore)

vero === 1 (falso - non uguale nel valore && tipo)

  • vero è booleano
  • 1 è int

È tutta una questione di tipi di dati.Prendi un BOOL (vero o falso) ad esempio:

true anche uguale 1 Efalse anche uguale 0

IL == non si preoccupa dei tipi di dati durante il confronto:Quindi, se avessi una variabile pari a 1 (che potrebbe anche essere true):

$var=1;

E poi confrontare con ==:

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

Ma $var in realtà non è uguale true, vero?Ha il valore int di 1 invece, che a sua volta è uguale a vero.

Con ===, i tipi di dati vengono controllati per assicurarsi che le due variabili/oggetti/qualunque cosa utilizzino lo stesso tipo.

Quindi, se lo facessi

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

quella condizione non sarebbe vera, come $var !== true solo == true (se sai cosa voglio dire).

Perché avresti bisogno di questo?

Semplice: diamo un'occhiata a una delle funzioni di PHP: array_search():

IL array_search() La funzione cerca semplicemente un valore in un array e restituisce la chiave dell'elemento in cui è stato trovato il valore.Se non è stato possibile trovare il valore nell'array, restituisce falso.Ma cosa succederebbe se facessi un array_search() su un valore memorizzato nel file primo elemento dell'array (che avrebbe la chiave dell'array di 0)....IL array_search() la funzione restituirebbe 0... che è uguale a falso...

Quindi se hai fatto:

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

Quindi, vedi come questo potrebbe essere un problema ora?

La maggior parte delle persone non lo usa == false quando si controlla se una funzione restituisce false.Invece, usano il !.Ma in realtà, questo è esattamente lo stesso dell'utilizzo ==false, quindi se hai fatto:

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

Quindi per cose del genere, utilizzeresti il ​​file === invece, in modo che il tipo di dati venga controllato.

Un esempio è che un attributo del database può essere nullo o "":

$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

Dato x = 5

1) Operatore:== è "uguale a". x == 8 è falso
2) Operatore:=== è "esattamente uguale a" (valore e tipo) x === 5 è vero, x === "5" è falso

Alcuni esempi

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

== Confronta solo il valore, non si preoccupa dei tipi di dati

contro

=== Confronta i valori e i tipi di dati

$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

Stai attento però.Ecco un problema noto.

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

contro

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

In breve, === funziona allo stesso modo di == nella maggior parte degli altri linguaggi di programmazione.

PHP ti consente di fare confronti che non hanno davvero senso.Esempio:

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

Sebbene ciò consenta alcune "scorciatoie" interessanti, dovresti fare attenzione poiché una funzione che restituisce qualcosa che non dovrebbe (come "errore" invece di un numero) non verrà catturata e rimarrai a chiederti cosa è successo.

In PHP, == confronta i valori ed esegue la conversione del tipo se necessario (ad esempio, la stringa "12343sdfjskfjds" diventerà "12343" in un confronto tra numeri interi).=== confronterà il valore AND tipo e restituirà false se il tipo non è lo stesso.

Se guardi il manuale PHP, vedrai che molte funzioni restituiscono "false" se la funzione fallisce, ma potrebbero restituire 0 in uno scenario di successo, motivo per cui consigliano di fare "if (function() !== false)" per evitare errori.

Dovresti usare === per verificare se una funzione o una variabile è falsa anziché semplicemente equivalere a falso (zero o una stringa vuota).

$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 questo caso strpos restituirebbe 0 che equivarrebbe a false nel test

if ($pos == false)

O

if (!$pos)

che non è quello che vuoi qui.

Per quanto riguarda quando usarne uno rispetto all'altro, prendi ad esempio the fwrite() funzione in PHP.

Questa funzione scrive il contenuto in un flusso di file.Secondo PHP, "fwrite() restituisce il numero di byte scritti o FALSE in caso di errore.".Se vuoi verificare se la chiamata alla funzione ha avuto successo, questo metodo è difettoso:

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

Può restituire zero (ed è considerato riuscito) e la tua condizione viene comunque attivata.Il modo giusto sarebbe:

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

PHP è un linguaggio vagamente tipizzato.L'uso dell'operatore doppio uguale consente un controllo approssimativo di una variabile.

Controllare liberamente un valore consentirebbe ad alcuni valori simili, ma non uguali, di essere considerati uguali:

  • ''
  • nullo
  • falso
  • 0

Tutti questi valori equivarrebbero a uguali utilizzando l'operatore doppio uguale.

php == è un operatore di confronto che confronta il valore delle variabili.Ma === confronta il valore e il tipo di dati.

Per esempio,

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

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

In questo caso l'output sarà "Le variabili sono uguali", anche se i loro tipi di dati sono diversi.

Ma se usiamo === invece di ==, l'output sarà "Le variabili non sono uguali".Il php confronta prima il valore della variabile e poi il tipo di dati.Qui i valori sono gli stessi, ma i tipi di dati sono diversi.

Le variabili hanno un tipo e un valore.

  • $var = "test" è una stringa che contiene "test"
  • $var2 = 24 è un numero intero il cui valore è 24.

Quando usi queste variabili (in PHP), a volte non hai il tipo corretto.Ad esempio, se lo fai

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

PHP deve convertire ("cast") $var in intero.In questo caso, "$var == 1" è vero perché qualsiasi stringa non vuota viene convertita in 1.

Quando usi ===, controlla che il valore E IL TIPO siano uguali, quindi "$var === 1" è falso.

Ciò è utile, ad esempio, quando hai una funzione che può restituire false (in caso di errore) e 0 (risultato):

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

Questo codice è sbagliato come se myFunction() restituisce 0, viene castato su falso e sembra che ci sia un errore.Il codice corretto è:

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

perché il test è che il valore restituito "è booleano ed è falso" e non "può essere convertito in falso".

IL === l'operatore dovrebbe confrontare esatto uguaglianza dei contenuti mentre il == l'operatore confronterebbe l'uguaglianza semantica.In particolare costringerà le stringhe a numeri.

L’uguaglianza è un argomento vasto.Vedere l'articolo di Wikipedia sull'uguaglianza.

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

Tutte le risposte finora ignorano un problema pericoloso con ===.È stato notato di sfuggita, ma non sottolineato, che intero e doppio sono tipi diversi, quindi il seguente codice:

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

dà:

 equal
 not equal

Tieni presente che questo NON è un caso di "errore di arrotondamento".I due numeri sono esattamente uguali fino all'ultimo bit, ma hanno tipi diversi.

Questo è un brutto problema perché un programma che utilizza === può funzionare felicemente per anni se tutti i numeri sono sufficientemente piccoli (dove "abbastanza piccolo" dipende dall'hardware e dal sistema operativo su cui si sta eseguendo).Tuttavia, se per caso un intero risulta essere abbastanza grande da essere convertito in un double, il suo tipo viene cambiato "per sempre" anche se un'operazione successiva, o molte operazioni, potrebbero riportarlo ad un valore intero piccolo.E peggiora.Può diffondersi: l'infezione della doppia identità può essere trasmessa a qualsiasi cosa tocchi, un calcolo alla volta.

Nel mondo reale, ad esempio, è probabile che questo costituisca un problema nei programmi che gestiscono date successive all'anno 2038.In questo momento, i timestamp UNIX (numero di secondi dal 1970-01-01 00:00:00 UTC) richiederanno più di 32 bit, quindi la loro rappresentazione cambierà "magicamente" per raddoppiare su alcuni sistemi.Pertanto, se calcoli la differenza tra due tempi potresti ritrovarti con un paio di secondi, ma come un risultato doppio, anziché intero che si verifica nell'anno 2017.

Penso che questo sia molto peggio delle conversioni tra stringhe e numeri perché è sottile.Trovo facile tenere traccia di cos'è una stringa e cos'è un numero, ma tenere traccia del numero di bit in un numero è al di là delle mie capacità.

Quindi, nelle risposte sopra ci sono alcune belle tabelle, ma nessuna distinzione tra 1 (come intero) e 1 (doppio sottile) e 1.0 (doppio ovvio).Inoltre, il consiglio di usare sempre === e mai == non è eccezionale perché === a volte fallirà dove == funziona correttamente.Inoltre, JavaScript non è equivalente a questo riguardo perché ha un solo tipo numerico (internamente può avere diverse rappresentazioni bit per bit, ma non causa problemi per ===).

Il mio consiglio: non usare nessuno dei due.È necessario scrivere la propria funzione di confronto per risolvere davvero questo pasticcio.

Ci sono due differenze tra == E === in array e oggetti PHP che penso non siano stati menzionati qui;due array con diversi tipi di chiavi e oggetti.

Due array con diversi tipi di chiavi

Se hai un array con un ordinamento di chiavi e un altro array con un ordinamento di chiavi diverso, sono strettamente diversi (cioèutilizzando ===).Ciò potrebbe verificarsi se si ordina per chiave un array e si prova a confrontare l'array ordinato con quello originale.

Ad esempio, considera un array vuoto.Per prima cosa proviamo a inserire alcuni nuovi indici nell'array senza alcun ordinamento speciale.Un buon esempio potrebbe essere un array con stringhe come chiavi.Ora approfondiamo un esempio:

// Define an array
$arr = [];

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

Ora abbiamo un array di chiavi non ordinate (ad esempio, "lui" è venuto dopo "tu").Considera lo stesso array, ma abbiamo ordinato le sue chiavi in ​​ordine alfabetico:

// Declare array
$alphabetArr = [];

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

Mancia:È possibile ordinare un array per chiave utilizzando ksort() funzione.

Ora hai un altro array con un ordinamento di chiavi diverso dal primo.Quindi li confronteremo:

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

Nota:Può essere ovvio, ma confrontandone due diverso gli array che utilizzano il confronto rigoroso risultano sempre false.Tuttavia, due array arbitrari possono essere uguali utilizzando === o no.

Tu diresti:"Questa differenza è trascurabile".Quindi dico che è una differenza e dovrebbe essere considerata e potrebbe accadere in qualsiasi momento.Come accennato in precedenza, l'ordinamento delle chiavi in ​​un array ne è un buon esempio.

Oggetti

Tieni a mente, due oggetti diversi non sono mai rigorosamente uguali.Questi esempi potrebbero aiutare:

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

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

Nota:Assegnare un oggetto a un'altra variabile non crea una copia, piuttosto crea un riferimento alla stessa posizione di memoria dell'oggetto. Vedere qui.

Nota:A partire da PHP7, classi anonime è stato aggiunto.Dai risultati, non c'è differenza tra new class {} E new stdClass() nei test di cui sopra.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top