it-swarm.it

Come fanno i PHP l'uguaglianza (== doppio uguale) e l'identità (=== triple equals) gli operatori di confronto differiscono?

Qual è la differenza tra == e ===?

  • Come funziona esattamente il paragone ==?
  • Come funziona esattamente il confronto ===

Quali sarebbero alcuni esempi utili?

451
nickf

L'operatore == esegue il cast tra due diversi tipi se sono diversi, mentre l'operatore === esegue un "confronto typesafe". 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

Avviso : 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)
235
Patrick Glandien

Un'immagine vale più di mille parole:

Grafico di uguaglianza == di PHP Double Equals:

 enter image description here

PHP Triple Equals === Tabella delle uguaglianze:

 enter image description here

Codice sorgente per creare queste immagini:

https://github.com/sentientmachine/php_equality_charts

Meditazione Guru

Coloro che desiderano mantenere la loro sanità mentale, non leggere oltre.

  1. == converte gli operandi sinistro e destro in numeri quando possibile 123 == "123foo", ma "123" != "123foo"
  2. Una stringa esadecimale tra virgolette è a volte un galleggiante e verrà lanciata contro di essa.
  3. == non è transitivo perché "0"== 0 e 0 == "" ma "0" != ""
  4. "6" == " 6", "4.2" == "4.20" e "133" == "0133" ma 133 != 0133, perché 0133 è ottale. Ma "0x10" == "16" e "1e3" == "1000"
  5. Le variabili PHP che non sono state ancora dichiarate sono false.

  6. False == 0, "", [] e "0".

  7. Quando i numeri sono abbastanza grandi sono == Infinity.
  8. NAN non == stesso, ma è vero.
  9. Una nuova lezione è == a 1.
  10. False è il valore più pericoloso perché False è == alla maggior parte delle altre variabili, per lo più sconfiggendo il suo scopo.

Speranza:

Se usi PHP, non usi l'operatore di doppio equals, usa sempre triple equals.

58
Eric Leschinski

Per quanto riguarda JavaScript:

L'operatore === funziona come l'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 mostrerà 'x e y sono uguali', ma non 'x e 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');
}
38
user1684

Un'aggiunta alle altre risposte relative al confronto degli 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 membro, $a == $b restituisce true.

=== confronta l'ID dell'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
22
soulmerge

In termini più semplici:

== controlla se equivalent (solo valore)

=== controlla se same (value && type)


Equivalente rispetto a Same: An Analogy

1 + 1 = 2 + 0 (equivalente)

1 + 1 = 1 + 1 (stesso)


In PHP:

true == 1 (true - equivalente in valore)

true === 1 (false - non uguale nel valore e nel tipo)

  • true is booleano
  • 1 è int
13
silver

È tutto basato sui tipi di dati. Prendi un BOOL (vero o falso) per esempio:

true eguaglia anche 1 e false eguaglia 0

Il == non si preoccupa dei tipi di dati quando si confrontano: Quindi se si ha una variabile che è 1 (che potrebbe anche essere true):

$var=1;

E poi confrontalo con ==:

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

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

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

Quindi se l'avessi fatto

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

quella condizione non sarebbe vera, poiché $var !== true è solo == true (se sai cosa intendo).

Perché dovresti aver bisogno di questo?

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

La funzione array_search() 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 hai fatto un array_search() su un valore che è stato memorizzato nel primo elemento dell'array (che avrebbe la chiave dell'array di 0) .... la funzione array_search() restituirebbe 0 ... che è uguale a falso ..

Quindi se l'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 usa == false quando verifica se una funzione restituisce false. Invece, usano !. Ma in realtà, questo è esattamente lo stesso di usare ==false, quindi se lo facessi:

$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 ===, in modo che il tipo di dati sia selezionato.

8
user849137

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
8
fico7489

Dato x = 5

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

6
Mannusanghi

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.

Post scriptum.

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

vs.

=== Confronta i valori e i tipi di dati

4
Mohit Tanwani

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

PHP ti permette di fare paragoni che non hanno molto 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 ti verrà chiesto 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 interi). === confronterà il valore AND type e restituirà false se il tipo non è lo stesso.

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

3
Christian P.
$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 famigerato.

// '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
Seph

PHP è un linguaggio vagamente dattiloscritto. L'utilizzo dell'operatore doppio uguale consente di controllare liberamente una variabile.

Il controllo approssimativo di un valore consentirebbe per alcuni valori simili, ma non uguali, di essere identici allo stesso modo:

  • ''
  • nullo
  • false

Tutti questi valori equivarrebbero uguali usando il doppio operatore uguale.

2
Cory Collier

Dovresti usare === per verificare se una funzione o una variabile è falsa piuttosto che equivale a false (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 lo strpos restituirebbe 0 che equivarrebbe a falso nel test

if ($pos == false)

o

if (!$pos)

che non è quello che vuoi qui.

2
Stacey Richards

Per quanto riguarda quando utilizzare uno sull'altro, prendi ad esempio la funzione fwrite() 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 successo) e la tua condizione viene comunque attivata. La strada giusta sarebbe:

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

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 prima confronta il valore della variabile e quindi il tipo di dati. Qui i valori sono gli stessi, ma i tipi di dati sono diversi.

1
2rahulsk

Tutte le risposte finora ignorano un problema pericoloso con ===. È stato notato di passaggio, ma non sottolineato, che i numeri interi e i tipi doppi sono 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 problema sgradevole 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 in esecuzione). Tuttavia, se per caso, un intero sembra essere abbastanza grande da essere convertito in un doppio, il suo tipo viene modificato "per sempre" anche se un'operazione successiva, o molte operazioni, potrebbero riportarlo a un valore intero piccolo. E, peggiora. Può diffondersi - l'infezione a doppio taglio può essere trasmessa a tutto ciò che tocca, un calcolo alla volta. 

Nel mondo reale, questo è probabilmente un problema nei programmi che gestiscono date oltre l'anno 2038, per esempio. A questo punto, i timestamp UNIX (numero di secondi dal 1970-01-01 00:00:00 UTC) richiederanno più di 32 bit, quindi la loro rappresentazione "magicamente" passerà a raddoppiare su alcuni sistemi. Pertanto, se si calcola la differenza tra due volte si potrebbe finire con un paio di secondi, ma come un doppio, piuttosto che 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 qual è un numero, ma tenere traccia del numero di bit in un numero è oltre me.

Quindi, nelle risposte sopra ci sono alcune tabelle di Nizza, ma nessuna distinzione tra 1 (come numero intero) e 1 (doppio sottile) e 1.0 (doppio ovvio). Inoltre, i consigli che dovresti sempre usare === e mai == non sono grandi perché === a volte falliscono dove == funziona correttamente. Inoltre, JavaScript non è equivalente in questo senso perché ha solo un tipo di numero (internamente può avere rappresentazioni differenti bit-saggio, ma non causa problemi per ===).

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

1
DavidWalley
<?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
Sathish

Le variabili hanno un tipo e un valore.

  • $ var = "test" è una stringa che contiene "test"
  • $ var2 = 24 è un valore intero di vhose 24.

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 ("cast") $ var in intero. In questo caso, "$ var == 1" è vero perché ogni stringa non vuota viene castata su 1.

Quando si usa ===, si controlla che il valore AND THE TYPE siano uguali, quindi "$ var === 1" è falso.

Ciò è utile, ad esempio, quando si ha una funzione che può restituire false (su errore) e 0 (risultato):

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

Questo codice è sbagliato come se myFunction() restituisce 0, viene castato in false e sembra che tu abbia 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 castato in falso".

1
ofaurax

L'operatore === dovrebbe confrontare l'uguaglianza di contenuto exact mentre l'operatore == confronta l'uguaglianza semantica. In particolare, costringerà le stringhe ai numeri.

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

1
kmkaplan

Ci sono due differenze tra == e === in PHP array e oggetti che penso non abbiano menzionato qui; due array con diversi tipi di chiavi e oggetti.

Due array con diversi tipi di chiavi

Se si dispone di un array con un ordinamento di chiavi e un altro array con un diverso ordinamento di chiavi, sono strettamente diversi (ossia utilizzando ===). Ciò potrebbe causare se si ordina una matrice in chiave e si prova a confrontare l'array ordinato con quello originale.

Ad esempio, considera una matrice vuota. Per prima cosa, proviamo a inserire alcuni nuovi indici nell'array senza alcun tipo 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 es., "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";

Suggerimento: puoi ordinare un array per chiave usando ksort () function.

Ora hai un altro array con un diverso tipo di chiave dal primo. Quindi, li compareremo:

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

Nota: Può essere ovvio, ma confrontare due array diversiusando il confronto rigoroso risulta sempre false. Tuttavia, due array arbitrari possono essere uguali usando === oppure no.

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 è un buon esempio di ciò.

Oggetti

Tieni presente, due oggetti diversi non sono mai rigorosi-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 .

Note: A partire da PHP7, classi anonime è stato aggiunto. Dai risultati, non vi è alcuna differenza tra new class {} e new stdClass() nei test di cui sopra.

0
MAChitgarha