Risposte:
==
e===
La differenza tra l' ==
operatore vagamente uguale e l' ===
operatore identico rigoroso è spiegata esattamente nel manuale :
Operatori di confronto
┌──────────┬───────────┬────────────────────────── ─────────────────────────────────┐ │ Esempio │ Nome │ Risultato │ ├──────────┼───────────┼────────────────────────── ─────────────────────────────────┤ │ $ a == $ b │ Uguale │ VERO se $ a è uguale a $ b dopo la giocoleria di tipo. │ │ $ a === $ b │ Identico │ VERO se $ a è uguale a $ b, e sono dello stesso tipo. │ └──────────┴───────────┴────────────────────────── ─────────────────────────────────┘
==
Confronto vagamente ugualeSe stai usando l' ==
operatore, o qualsiasi altro operatore di confronto che utilizza un confronto vagamente come !=
, <>
o ==
, devi sempre guardare il contesto per vedere cosa, dove e perché qualcosa viene convertito per capire cosa sta succedendo.
Come riferimento ed esempio puoi vedere la tabella di confronto nel manuale :
Confronti sciolti con
==
┌─────────┬───────┬───────┬───────┬───────┬─────── ┬───────┬───────┬───────┬───────┬─────────┬─────── ┬───────┐ │ │ TRUE │ FALSE │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ array () │ "php" │ "" │ ├─────────┼───────┼───────┼───────┼───────┼─────── ┼───────┼───────┼───────┼───────┼─────────┼─────── ┼───────┤ │ VERO │ VERO │ FALSO │ VERO │ FALSO │ VERO │ VERO │ FALSO │ VERO │ FALSO │ FALSO │ VERO │ FALSO │ │ FALSO │ FALSO │ VERO │ FALSO │ VERO │ FALSO │ FALSO │ VERO │ FALSO │ VERO │ VERO │ FALSO │ VERO │ │ 1 │ VERO │ FALSO │ VERO │ FALSO │ FALSO │ VERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ 0 │ FALSO │ VERO │ FALSO │ VERO │ FALSO │ FALSO │ VERO │ FALSO │ VERO │ FALSO │ VERO │ VERO │ │ -1 │ VERO │ FALSO │ FALSO │ FALSO │ VERO │ FALSO │ FALSO │ VERO │ FALSO │ FALSO │ FALSO │ FALSO │ │ "1" │ VERO │ FALSO │ VERO │ FALSO │ FALSO │ VERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ "0" │ FALSO │ VERO │ FALSO │ VERO │ FALSO │ FALSO │ VERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ "-1" │ VERO │ FALSO │ FALSO │ FALSO │ VERO │ FALSO │ FALSO │ VERO │ FALSO │ FALSO │ FALSO │ FALSO │ │ NULL │ FALSE │ VERO │ FALSO │ VERO │ FALSO │ FALSO │ FALSO │ FALSO │ VERO │ VERO │ FALSO │ VERO │ │ array () │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ TRUE │ FALSE │ FALSE │ │ "php" │ VERO │ FALSO │ FALSO │ VERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERO │ FALSO │ │ "" │ FALSO │ VERO │ FALSO │ VERO │ FALSO │ FALSO │ FALSO │ FALSO │ VERO │ FALSO │ FALSO │ VERO │ └─────────┴───────┴───────┴───────┴───────┴─────── ┴───────┴───────┴───────┴───────┴─────────┴─────── ┴───────┘
===
Confronto identico rigorosoSe stai utilizzando l' ===
operatore o qualsiasi altro operatore di confronto che utilizza un confronto rigoroso come !==
o ===
, allora puoi sempre essere sicuro che i tipi non cambieranno magicamente , perché non ci sarà alcuna conversione in corso. Quindi, con un rigoroso confronto, il tipo e il valore devono essere gli stessi, non solo il valore.
Come riferimento ed esempio puoi vedere la tabella di confronto nel manuale :
Confronti rigorosi con
===
┌─────────┬───────┬───────┬───────┬───────┬─────── ┬───────┬───────┬───────┬───────┬─────────┬─────── ┬───────┐ │ │ TRUE │ FALSE │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ array () │ "php" │ "" │ ├─────────┼───────┼───────┼───────┼───────┼─────── ┼───────┼───────┼───────┼───────┼─────────┼─────── ┼───────┤ │ VERO │ VERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ FALSO │ FALSO │ VERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ 1 │ FALSO │ FALSO │ VERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ 0 │ FALSE │ FALSE │ FALSE │ VERO │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ │ -1 │ FALSO │ FALSO │ FALSO │ FALSO │ VERO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ │ "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 │ └─────────┴───────┴───────┴───────┴───────┴─────── ┴───────┴───────┴───────┴───────┴─────────┴─────── ┴───────┘
true
oppure false
. È facile da lanciare. Tutti gli altri valori hanno, per tutti gli scopi pratici, combinazioni praticamente illimitate. È "five" == 5
? array(0) == 0
? array(0,0,0) == 0
? 0.0000000000000000000000000000000000000000000000000001 == array()
?
false
matrici diverse in javascript, ma true
per PHP purché i loro valori siano uguali .
"000" != "00"
, "000" == null
, "000" == false
, "0x0" == false
, array() == 0
, false != null
, array() != null
, false == "0x0"
, false == "000"
. In PHP, è un comportamento opposto: "000" == "00"
, "000" != null
, "000" != false
, "0x0" != false
, array() != 0
, false == null
, array() == null
, false != "0x0"
, false != "000"
.
L'operatore == esegue il cast tra due tipi diversi se sono diversi, mentre l'operatore === esegue un "confronto di tipi di errori". Ciò significa che restituirà true 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
Avvertenza : due istanze della stessa classe con membri equivalenti NON corrispondono ===
all'operatore. Esempio:
$a = new stdClass();
$a->foo = "bar";
$b = clone $a;
var_dump($a === $b); // bool(false)
Un'immagine vale più di mille parole:
==
Grafico dell'uguaglianza PHP Double Equals :===
Grafico PHP Triple Equals Equality:Codice sorgente per creare queste immagini:
https://github.com/sentientmachine/php_equality_charts
Coloro che desiderano mantenere il loro buonsenso, non leggono oltre perché nulla di tutto ciò avrà alcun senso, tranne per dire che è così che è stato progettato il folle frattale del PHP.
NAN != NAN
ma NAN == true
. ==
convertirà gli operandi sinistro e destro in numeri se left è un numero. Quindi 123 == "123foo"
, ma"123" != "123foo"
Una stringa esadecimale tra virgolette è occasionalmente un float e sarà lanciata a sorpresa per fluttuare contro la tua volontà, causando un errore di runtime.
==
non è transitivo perché "0"== 0
, e 0 == ""
ma"0" != ""
==
."6" == " 6"
, "4.2" == "4.20"
e "133" == "0133"
ma 133 != 0133
. Ma "0x10" == "16"
ed "1e3" == "1000"
esporre quella conversione di stringa a sorpresa in ottale avverrà sia senza la tua istruzione che con il tuo consenso, causando un errore di runtime.
False == 0
, ""
, []
E "0"
.
Quando i numeri sono abbastanza grandi, sono == Infinito.
Una nuova classe è == a 1.
Se si utilizza PHP, non si utilizzerà l'operatore double egals perché se si utilizzano triple uguale, gli unici casi limite di cui preoccuparsi sono NAN e numeri così vicini all'infinito che vengono lanciati all'infinito. Con il doppio uguale, qualsiasi cosa può essere sorpresa ==
a qualsiasi cosa o, o può essere sorpresa, lanciata contro la tua volontà e !=
verso qualcosa di cui dovrebbe ovviamente essere uguale.
Ovunque tu usi ==
in PHP c'è un cattivo odore di codice a causa degli 85 bug in esso esposti esposti a regole di casting implicite che sembrano progettate da milioni di programmatori che programmano il moto 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, nell'esempio seguente verrà visualizzato "xey sono uguali", ma non "xey y 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 di oggetti:
== confronta gli oggetti usando il nome dell'oggetto e i loro valori. Se due oggetti sono dello stesso tipo e hanno gli stessi valori dei membri, $a == $b
produce true.
=== confronta l'id interno dell'oggetto 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)
=== verifica se lo stesso (valore & tipo)
equivalente o uguale: un'analogia
1 + 1 = 2 + 0 (equivalente)
1 + 1 = 1 + 1 (stesso)
in PHP:
true == 1 (true - equivalente in valore)
true === 1 (false - non è lo stesso in value && type)
Si tratta di tipi di dati. Prendi un BOOL
(vero o falso) per esempio:
true
anche uguale 1
e
false
anche uguale0
Al confronto ==
non interessano i tipi di dati: Quindi, se avessi una variabile che è 1 (che potrebbe anche essere true
):
$var=1;
E quindi confrontare con ==
:
if ($var == true)
{
echo"var is true";
}
Ma in $var
realtà non è uguale true
, vero? Ha invece il valore int di 1
, che a sua volta è uguale a vero.
Con ===
, i tipi di dati sono controllati per assicurarsi che le due variabili / oggetti / qualunque cosa stiano usando lo stesso tipo.
Quindi se lo facessi
if ($var === true)
{
echo "var is true";
}
quella condizione non sarebbe vera, in $var !== true
quanto solo == true
(se sai cosa intendo).
Perché dovresti averne bisogno?
Semplice: diamo un'occhiata a una delle funzioni di PHP array_search()
:
La array_search()
funzione cerca semplicemente un valore in un array e restituisce la chiave dell'elemento in cui è stato trovato il valore. Se il valore non è stato trovato nell'array, restituisce false . Ma cosa succede se si fa un array_search()
valore memorizzato nel primo elemento dell'array (che avrebbe la chiave dell'array di 0
) .... la array_search()
funzione restituirebbe 0 ... che è uguale a false ..
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?
Molte persone non usano == false
per verificare se una funzione restituisce false. Invece, usano il !
. Ma in realtà, questo è esattamente uguale all'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, dovresti usare ===
invece, in modo che il tipo di dati sia verificato.
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
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 utilizziamo === anziché ==, l'output sarà "Le variabili non sono uguali". Il php confronta prima il valore della variabile e quindi il tipo di dati. Qui i valori sono gli stessi, ma i tipi di dati sono diversi.
Dato x = 5
1) Operatore: == è "uguale a". x == 8
è falso
2) Operatore: === è "esattamente uguale a" (valore e tipo) x === 5
è vero, x === "5"
è falso
$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...
}
vs.
// 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)
...
Mentre questo consente alcune "scorciatoie" interessanti, dovresti fare attenzione poiché una funzione che restituisce qualcosa che non dovrebbe (come "errore" anziché un numero) non verrà catturata e ti lascerai 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 di numeri interi). === confronta il valore AND e restituisce false se il tipo non è lo stesso.
Se guardi nel manuale di 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.
Pochi degli 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 preoccuperà dei tipi di dati
vs.
=== Confronta i valori e i tipi di dati
Dovresti usare === per verificare se una funzione o una variabile è falsa piuttosto che 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 restituirà 0 che equivarrebbe a false nel test
if ($pos == false)
o
if (!$pos)
che non è quello che vuoi qui.
Per quanto riguarda quando usare uno sopra l'altro, prendiamo ad esempio il 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 si desidera verificare se la chiamata di funzione ha avuto esito positivo, questo metodo è difettoso:
if (!fwrite(stuff))
{
log('error!');
}
Può restituire zero (ed è considerato corretto) 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 double equal consente di verificare liberamente una variabile.
Controllare liberamente un valore consentirebbe ad alcuni valori simili, ma non uguali, di eguagliare lo stesso:
Tutti questi valori equivarrebbero come uguali utilizzando l'operatore double equal.
Le variabili hanno un tipo e un valore.
Quando usi queste variabili (in PHP), a volte non hai il buon tipo. Ad esempio, se lo fai
if ($var == 1) {... do something ...}
PHP deve convertire ("in cast") $ var in numero intero. In questo caso, "$ var == 1" è vero perché qualsiasi stringa non vuota viene lanciata su 1.
Quando si utilizza ===, si controlla che il valore E IL TIPO siano uguali, quindi "$ var === 1" è falso.
Ciò è utile, ad esempio, quando si dispone di una funzione che può restituire false (in caso di errore) e 0 (risultato):
if(myFunction() == false) { ... error on myFunction ... }
Questo codice è errato come se myFunction()
restituisse 0, è impostato su false e sembra che si sia verificato un errore. Il codice corretto è:
if(myFunction() === false) { ... error on myFunction ... }
perché il test è che il valore restituito "è un valore booleano ed è falso" e non "può essere impostato su falso".
L' ===
operatore dovrebbe confrontare l' uguaglianza esatta del contenuto mentre l' ==
operatore dovrebbe confrontare l'uguaglianza semantica. In particolare costringerà le stringhe ai numeri.
L'uguaglianza è un argomento vasto. Vedi 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 passaggio, 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
Si noti 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 usa === può funzionare felicemente per anni se tutti i numeri sono abbastanza piccoli (dove "abbastanza piccolo" dipende dall'hardware e dal sistema operativo su cui stai eseguendo). Tuttavia, se per caso, un intero risulta abbastanza grande da essere convertito in doppio, il suo tipo viene modificato "per sempre" anche se un'operazione successiva, o molte operazioni, potrebbero riportarlo a un piccolo numero intero. E peggiora. Può diffondersi: l'infezione da doppiazza può essere trasmessa a tutto ciò che tocca, un calcolo alla volta.
Nel mondo reale, questo è probabilmente un problema nei programmi che gestiscono le date oltre l'anno 2038, per esempio. Al momento, i timestamp UNIX (numero di secondi dal 1970-01-01 00:00:00 UTC) richiedono più di 32 bit, quindi la loro rappresentazione "magicamente" passerà al doppio su alcuni sistemi. Pertanto, se si calcola la differenza tra due volte, si potrebbe finire con un paio di secondi, ma come un doppio, anziché il risultato 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 cosa sia una stringa e cosa sia un numero, ma tenere traccia del numero di bit in un numero è oltre me.
Quindi, nelle risposte sopra ci sono alcune belle tabelle, ma nessuna distinzione tra 1 (come un numero intero) e 1 (doppio sottile) e 1.0 (doppio evidente). Inoltre, i consigli che dovresti sempre usare === e mai == non sono grandi perché === a volte fallisce dove == funziona correttamente. Inoltre, JavaScript non è equivalente a questo proposito perché ha solo un tipo di numero (internamente può avere rappresentazioni bit-bit diverse, ma non causa problemi per ===).
Il mio consiglio: non usare nessuno dei due. È necessario scrivere la propria funzione di confronto per risolvere davvero questo casino.
Ci sono due differenze tra ==
e===
in array e oggetti PHP che penso non abbiano menzionato qui; due matrici con diversi tipi di chiavi e oggetti.
Se si dispone di un array con un ordinamento di chiavi e un altro array con un ordinamento di chiavi diverso, sono rigorosamente differenti (ovvero utilizzando ===
). Ciò può causare se si ordina un array di chiavi e si prova a confrontare l'array ordinato con quello originale.
Ad esempio, considera un array vuoto. Innanzitutto, proviamo a inviare alcuni nuovi indici all'array senza alcun ordinamento speciale. Un buon esempio potrebbe essere un array con stringhe come chiavi. Ora in profondità in 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 "te"). 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";
Suggerimento : puoi ordinare un array per chiave usando ksort () .
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 il confronto di due array diversi utilizzando un confronto rigoroso risulta sempre false
. Tuttavia, due array arbitrari possono essere uguali utilizzando===
o meno.
Diresti: "Questa differenza è trascurabile". Quindi dico che è una differenza e dovrebbe essere considerata e può accadere in qualsiasi momento. Come accennato in precedenza, l'ordinamento delle chiavi in un array ne è un buon esempio.
Tieni presente che 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 : l'assegnazione di un oggetto a un'altra variabile non crea una copia, ma crea un riferimento alla stessa posizione di memoria dell'oggetto. Vedere qui .
Nota : a partire da PHP7, sono state aggiunte classi anonime . Dai risultati, non vi è alcuna differenza tra new class {}
e new stdClass()
nei test sopra.