Como os operadores de comparação de igualdade (== duplo igual) e identidade (=== triplo igual) do PHP diferem?

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

Pergunta

Qual é a diferença entre == e ===?

  • Como exatamente o vagamente == trabalho de comparação?
  • Como exatamente o estrito === trabalho de comparação?

Quais seriam alguns exemplos úteis?

Foi útil?

Solução

Diferença entre == e ===

A diferença entre o vagamente == operador igual e o estrito === operador idêntico é explicado exatamente no manual:

Operadores de comparação

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

Vagamente == comparação igual

Se você estiver usando o == operador, ou qualquer outro operador de comparação que use comparação vaga, como !=, <> ou ==, você sempre tem que olhar para o contexto para ver o que, onde e por que algo é convertido para entender o que está acontecendo.

Convertendo regras

Tabela de comparação de tipos

Como referência e exemplo você pode ver a tabela de comparação no manual:

Comparações vagas com ==

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

Estrito === comparação idêntica

Se você estiver usando o === operador, ou qualquer outro operador de comparação que use comparação estrita, como !== ou ===, então você sempre pode ter certeza de que os tipos não magicamente mudança, porque não haverá conversão acontecendo.Portanto, com comparação estrita, o tipo e o valor devem ser iguais, não apenas o valor.

Tabela de comparação de tipos

Como referência e exemplo você pode ver a tabela de comparação no manual:

Comparações rigorosas com ===

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

Outras dicas

O operador == converte entre dois tipos diferentes se eles forem diferentes, enquanto o operador === executa uma 'comparação segura de tipo'.Isso significa que só retornará verdadeiro se ambos os operandos tiverem o mesmo tipo e o mesmo valor.

Exemplos:

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

Aviso:duas instâncias da mesma classe com membros equivalentes NÃO correspondem ao === operador.Exemplo:

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

Uma imagem vale mais que mil palavras:

PHP duplo igual == gráfico de igualdade:

enter image description here

PHP triplo igual === Gráfico de igualdade:

enter image description here

Código fonte para criar essas imagens:

https://github.com/sentientmachine/php_equality_charts

meditação de guru

Aqueles que desejam manter a sanidade, não leiam mais porque nada disso fará sentido, exceto dizer que foi assim que o fractal da insanidade do PHP foi projetado.

  1. NAN != NAN mas NAN == true.
  2. == converterá os operandos esquerdo e direito em números se left for um número.Então 123 == "123foo", mas "123" != "123foo"
  3. Uma string hexadecimal entre aspas é ocasionalmente um float e será lançada de surpresa para flutuar contra sua vontade, causando um erro de tempo de execução.

  4. == não é transitivo porque "0"== 0, e 0 == "" mas "0" != ""

  5. Variáveis ​​PHP que ainda não foram declaradas são falsas, embora o PHP tenha uma maneira de representar variáveis ​​indefinidas, esse recurso é desabilitado com ==.
  6. "6" == " 6", "4.2" == "4.20", e "133" == "0133" mas 133 != 0133.Mas "0x10" == "16" e "1e3" == "1000" expor essa conversão surpresa de string para octal ocorrerá sem sua instrução ou consentimento, causando um erro de tempo de execução.

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

  8. Quando os números são grandes o suficiente, eles são == Infinito.

  9. Uma nova classe é == para 1.

  10. False é o valor mais perigoso porque False é == para a maioria das outras variáveis, principalmente anulando seu propósito.

Ter esperança:

Se você estiver usando PHP, você não deve usar o operador de igual duplo porque se você usar igual triplo, os únicos casos extremos com os quais se preocupar são NAN e números tão próximos do infinito que são lançados ao infinito.Com dois iguais, tudo pode ser surpresa == para qualquer coisa ou, ou pode ser surpresa lançada contra sua vontade e != a algo do qual deveria obviamente ser igual.

Em qualquer lugar que você usa == em PHP é um mau cheiro de código por causa dos 85 bugs expostos por regras de conversão implícitas que parecem projetadas por milhões de programadores que programam por movimento browniano.

Em relação ao JavaScript:

O operador === funciona da mesma forma que o operador ==, mas exige que seus operandos tenham não apenas o mesmo valor, mas também o mesmo tipo de dados.

Por exemplo, o exemplo abaixo exibirá 'xey são iguais', mas não 'xey são idênticos'.

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

Uma adição às outras respostas relativas à comparação de objetos:

== compara objetos usando o nome do objeto e seus valores.Se dois objetos forem do mesmo tipo e tiverem os mesmos valores de membro, $a == $b produz verdadeiro.

=== compara o ID do objeto interno dos objetos.Mesmo que os membros sejam iguais, $a !== $b se eles não forem exatamente o mesmo objeto.

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

Em termos mais simples:

== verifica se equivalente (somente valor)

=== verifica se o mesmo (valor && tipo)


Equivalente vs.Mesmo:Uma analogia

1 + 1 = 2 + 0 (equivalente)

1 + 1 = 1 + 1 (mesmo)


Em PHP:

verdadeiro == 1 (verdadeiro - equivalente em valor)

verdadeiro === 1 (falso - não é o mesmo em valor && tipo)

  • verdade é boleano
  • 1 é interno

É tudo uma questão de tipos de dados.Dê uma BOOL (verdadeiro ou falso), por exemplo:

true também é igual 1 efalse também é igual 0

O == não se importa com os tipos de dados ao comparar:Então, se você tivesse uma variável que fosse 1 (que também poderia ser true):

$var=1;

E então compare com o ==:

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

Mas $var na verdade não é igual true, não é?Tem o valor int de 1 em vez disso, que por sua vez é igual a verdadeiro.

Com ===, os tipos de dados são verificados para garantir que as duas variáveis/objetos/o que quer que esteja usando o mesmo tipo.

Então, se eu fizesse

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

essa condição não seria verdadeira, pois $var !== true isso só == true (se você souber o que quero dizer).

Por que você precisa disso?

Simples – vamos dar uma olhada em uma das funções do PHP: array_search():

O array_search() A função simplesmente procura um valor em um array e retorna a chave do elemento em que o valor foi encontrado.Se o valor não puder ser encontrado no array, ele retornará falso.Mas, e se você fizesse um array_search() em um valor que foi armazenado no primeiro elemento da matriz (que teria a chave do array de 0)....o array_search() função retornaria 0...que é igual a falso..

Então, se você fez:

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

Então, você vê como isso pode ser um problema agora?

A maioria das pessoas não usa == false ao verificar se uma função retorna falso.Em vez disso, eles usam o !.Mas, na verdade, isso é exatamente o mesmo que usar ==false, então se você fez:

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

Então, para coisas assim, você usaria o === em vez disso, para que o tipo de dados seja verificado.

Um exemplo é que um atributo do banco de dados pode ser nulo ou "":

$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

Dado x = 5

1) Operador:== é "igual a". x == 8 é falso
2) Operador:=== é "exatamente igual a" (valor e tipo) x === 5 é verdade, x === "5" é falso

Poucos exemplos

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.

P.S.

== Compara apenas o valor, não se preocupa com os tipos de dados

vs.

=== Compara os valores e tipos de dados

$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

Porém, tenha cuidado.Aqui está um problema notório.

// '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...
}

Resumindo, === funciona da mesma maneira que == na maioria das outras linguagens de programação.

PHP permite fazer comparações que realmente não fazem sentido.Exemplo:

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

Embora isso permita alguns "atalhos" interessantes, você deve tomar cuidado, pois uma função que retorna algo que não deveria (como "erro" em vez de um número) não será detectada e você ficará se perguntando o que aconteceu.

Em PHP, == compara valores e realiza conversão de tipo se necessário (por exemplo, a string "12343sdfjskfjds" se tornará "12343" em uma comparação de inteiros).=== comparará o valor E o tipo e retornará falso se o tipo não for o mesmo.

Se você olhar no manual do PHP, verá que muitas funções retornam "false" se a função falhar, mas podem retornar 0 em um cenário de sucesso, e é por isso que recomendam fazer "if (function() !== false)" para evitar erros.

Você usaria === para testar se uma função ou variável é falsa, em vez de apenas igualar a falso (zero ou uma string vazia).

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

Neste caso, strpos retornaria 0, o que equivaleria a falso no teste

if ($pos == false)

ou

if (!$pos)

que não é o que você quer aqui.

Quanto a quando usar um em vez do outro, tome por exemplo o fwrite() função em PHP.

Esta função grava conteúdo em um fluxo de arquivo.De acordo com PHP, "fwrite() retorna o número de bytes gravados ou FALSE em caso de erro.".Se você quiser testar se a chamada de função foi bem-sucedida, este método é falho:

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

Ele pode retornar zero (e é considerado bem-sucedido) e sua condição ainda é acionada.O caminho certo seria:

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

PHP é uma linguagem de digitação livre.Usar o operador duplo igual permite uma verificação frouxa de uma variável.

A verificação vaga de um valor permitiria que alguns valores semelhantes, mas não iguais, fossem iguais:

  • ''
  • nulo
  • falso
  • 0

Todos esses valores seriam iguais usando o operador duplo igual.

php == é um operador de comparação que compara o valor das variáveis.Mas === compara o valor e o tipo de dados.

Por exemplo,

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

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

Neste caso a saída será 'Variáveis ​​são iguais', mesmo que seus tipos de dados sejam diferentes.

Mas se usarmos === em vez de ==, a saída será 'Variáveis ​​não são iguais'.O php primeiro compara o valor da variável e depois o tipo de dados.Aqui os valores são iguais, mas os tipos de dados são diferentes.

Variáveis ​​possuem um tipo e um valor.

  • $var = "test" é uma string que contém "test"
  • $var2 = 24 é um número inteiro cujo valor é 24.

Quando você usa essas variáveis ​​(em PHP), às vezes você não tem o tipo bom.Por exemplo, se você fizer

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

PHP tem que converter ("para converter") $var em inteiro.Nesse caso, "$var == 1" é verdadeiro porque qualquer string não vazia é convertida em 1.

Ao usar ===, você verifica se o valor AND THE TYPE são iguais, então "$var === 1" é falso.

Isso é útil, por exemplo, quando você tem uma função que pode retornar false (em caso de erro) e 0 (resultado):

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

Este código está errado como se myFunction() retorna 0, é convertido em falso e parece haver um erro.O código correto é:

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

porque o teste é que o valor de retorno "é booleano e falso" e não "pode ​​ser convertido em falso".

O === operador deve comparar exato igualdade de conteúdo enquanto o == operador compararia a igualdade semântica.Em particular, forçará strings a números.

A igualdade é um assunto vasto.Ver o artigo da Wikipedia sobre igualdade.

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

Todas as respostas até agora ignoram um problema perigoso com ===.Foi observado de passagem, mas não enfatizado, que inteiro e duplo são tipos diferentes, portanto o código a seguir:

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

dá:

 equal
 not equal

Observe que este NÃO é um caso de "erro de arredondamento".Os dois números são exatamente iguais até o último bit, mas têm tipos diferentes.

Este é um problema desagradável porque um programa que usa === pode funcionar perfeitamente por anos se todos os números forem pequenos o suficiente (onde "suficientemente pequeno" depende do hardware e do sistema operacional em que você está executando).No entanto, se por acaso um número inteiro for grande o suficiente para ser convertido em um duplo, seu tipo será alterado "para sempre", mesmo que uma operação subsequente, ou muitas operações, possa trazê-lo de volta a um número inteiro pequeno em valor.E fica pior.Ela pode se espalhar - a infecção dupla pode ser transmitida a qualquer coisa que toque, um cálculo de cada vez.

No mundo real, é provável que isto seja um problema em programas que tratam de datas posteriores ao ano 2038, por exemplo.Neste momento, os carimbos de data/hora UNIX (número de segundos desde 1970-01-01 00:00:00 UTC) exigirão mais de 32 bits, portanto, sua representação mudará "magicamente" para o dobro em alguns sistemas.Portanto, se você calcular a diferença entre dois tempos, poderá acabar com alguns segundos, mas como um dobro, em vez do resultado inteiro que ocorre no ano de 2017.

Acho que isso é muito pior do que conversões entre strings e números porque é sutil.Acho fácil controlar o que é uma string e o que é um número, mas controlar o número de bits em um número está além da minha capacidade.

Portanto, nas respostas acima existem algumas tabelas interessantes, mas nenhuma distinção entre 1 (como um número inteiro) e 1 (duplo sutil) e 1,0 (duplo óbvio).Além disso, o conselho de que você deve sempre usar === e nunca == não é bom porque === às vezes falha onde == funciona corretamente.Além disso, JavaScript não é equivalente nesse aspecto porque possui apenas um tipo de número (internamente pode ter diferentes representações bit a bit, mas não causa problemas para ===).

Meu conselho: não use nenhum dos dois.Você precisa escrever sua própria função de comparação para realmente consertar essa bagunça.

Existem duas diferenças entre == e === em arrays e objetos PHP que acho que não mencionei aqui;duas matrizes com diferentes tipos de chaves e objetos.

Duas matrizes com diferentes tipos de chaves

Se você tiver um array com uma classificação de chave e outro array com uma classificação de chave diferente, eles serão estritamente diferentes (ou seja,usando ===).Isso pode causar se você classificar uma matriz com chave e tentar comparar a matriz classificada com a original.

Por exemplo, considere um array vazio.Primeiro, tentamos enviar alguns novos índices para o array sem nenhuma classificação especial.Um bom exemplo seria um array com strings como chaves.Agora vamos aprofundar um exemplo:

// Define an array
$arr = [];

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

Agora, temos um array de chaves não classificadas (por exemplo, 'ele' veio depois de 'você').Considere o mesmo array, mas classificamos suas chaves em ordem alfabética:

// Declare array
$alphabetArr = [];

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

Dica:Você pode classificar um array por chave usando ksort() função.

Agora você tem outro array com uma classificação de chave diferente do primeiro.Então, vamos compará-los:

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

Observação:Pode ser óbvio, mas comparando dois diferente matrizes usando comparação estrita sempre resultam false.No entanto, duas matrizes arbitrárias podem ser iguais usando === ou não.

Você diria:“Essa diferença é insignificante”.Aí eu digo que é um diferencial e deve ser considerado e pode acontecer a qualquer momento.Conforme mencionado acima, a classificação de chaves em um array é um bom exemplo disso.

Objetos

Tenha em mente, dois objetos diferentes nunca são estritamente iguais.Esses exemplos ajudariam:

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

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

Observação:Atribuir um objeto a outra variável não cria uma cópia - em vez disso, cria uma referência ao mesmo local de memória que o objeto. Veja aqui.

Observação:A partir do PHP7, aulas anônimas foi adicionado.Pelos resultados, não há diferença entre new class {} e new stdClass() nos testes acima.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top