Como os operadores de comparação de igualdade do PHP (== duplos iguais) e identidade (=== triplos iguais) diferem?


509

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

  • Como exatamente a ==comparação frouxa funciona?
  • Como exatamente a ===comparação estrita funciona?

Quais seriam alguns exemplos úteis?

Respostas:


633

Diferença entre ==e===

A diferença entre o ==operador frouxamente igual e o ===operador estritamente idêntico é explicada exatamente no manual :

Operadores de comparação

┌────────────────────────────────────────────────────── ────────────────────────────────┐
│ Exemplo │ Nome │ Resultado │
├────────────────────────────────────────────────────── ────────────────────────────────┤
│ $ a == $ b │ Igual │ TRUE se $ a for igual a $ b após o malabarismo do tipo. │
A $ a === $ b │ Idêntico │ TRUE se $ a for igual a $ b, e eles são do mesmo tipo. │
└────────────────────────────────────────────────────── ────────────────────────────────┘

==Comparação fracamente igual

Se você estiver usando o ==operador, ou qualquer outro operador de comparação que faça comparações frouxas, como !=, <>ou ==, você sempre precisará olhar 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 frouxas com ==

┌────────────────┬──────────────────────────────────────────────── ┬───────┬──────────────┬───────┬──────────────────────────── ┬───────┐
│ UE TRUE │ FALSE │ 1 │ -1 │ "1" 0 "0" │ "-1" │ NULL │ array () │ "php" │ "" │
├────────────────┼───────┼────────────────────────────────── ┼───────┼───────┼──────┼───────┼───────────────────────────── ┼───────┤
│ VERDADEIRO │ VERDADEIRO AL FALSO │ VERDADEIRO │ FALSO │ VERDADEIRO │ VERDADEIRO AL FALSO │ VERDADEIRO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │
│ FALSO │ FALSO │ VERDADEIRO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ VERDADEIRO │ VERDADEIRO │ FALSO │ VERDADEIRO │
│ 1 │ VERDADEIRO AL FALSO │ VERDADEIRO │ FALSO │ FALSO │ VERDADEIRO AL FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │
│ 0 │ FALSO │ VERDADEIRO │ FALSO │ VERDADEIRO │ FALSO │ FALSO UE VERDADEIRO │ FALSO │ VERDADEIRO AL FALSO │ VERDADEIRO │ VERDADEIRO │
│ -1 │ VERDADEIRO AL FALSO │ FALSO │ FALSO │ VERDADEIRO AL FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │
1 "1" │ VERDADEIRO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │
0 "0" │ FALSO │ VERDADEIRO AL FALSO │ VERDADEIRO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │
-1 "-1" │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ VERDADEIRO AL FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │
│ NULL │ FALSO │ VERDADEIRO AL FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ VERDADEIRO │ FALSO │ VERDADEIRO │
│ matriz () │ FALSO │ VERDADEIRO AL FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ VERDADEIRO │ FALSO │ FALSO │
Ph "php" │ VERDADEIRO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │
│ "" │ FALSO │ VERDADEIRO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO AL FALSO │ FALSO │ VERDADEIRO │
└────────────────┴───────┴────────────────────────────────── ┴───────┴───────┴──────┴───────┴───────────────────────────── ┴───────┘

===Comparação estrita e idêntica

Se você estiver usando o ===operador, ou qualquer outro operador de comparação que use comparação estrita como !==ou ===, poderá sempre ter certeza de que os tipos não serão alterados magicamente , porque não haverá conversão em andamento. Portanto, com comparação estrita, o tipo e o valor devem ser os mesmos, 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 ===

┌────────────────┬──────────────────────────────────────────────── ┬───────┬──────────────┬───────┬──────────────────────────── ┬───────┐
│ UE TRUE │ FALSE │ 1 │ -1 │ "1" 0 "0" │ "-1" │ NULL │ array () │ "php" │ "" │
├────────────────┼───────┼────────────────────────────────── ┼───────┼───────┼──────┼───────┼───────────────────────────── ┼───────┤
│ VERDADEIRO │ VERDADEIRO AL FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │
│ FALSO │ FALSO │ VERDADEIRO AL FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │
│ 1 │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │
│ 0 │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │
│ -1 AL FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │
1 "1" │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │
0 "0" │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │
-1 "-1" │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO AL FALSO │ FALSO │ FALSO │ FALSO │
│ NULL │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │ FALSO │
│ matriz () │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │ FALSO │
Ph "php" │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │ FALSO │
│ "" │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO AL FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ FALSO │ VERDADEIRO │
└────────────────┴───────┴────────────────────────────────── ┴───────┴───────┴──────┴───────┴───────────────────────────── ┴───────┘

66
alguém mais acha estranho "000" == "0000"?
nickf

36
O que sempre me surpreende é que false == array () e false == 0 mas array ()! = 0, então false == array ()! = / == 0? isso me parece estranho.
Pim Jager

4
@Pim ... continuação: veja desta maneira: convertendo para um BOOL, qualquer valor só precisa cair em um dos dois lados, trueou false. Isso é fácil de lançar. Todos os outros valores têm, para todos os efeitos práticos, combinações praticamente ilimitadas. É "five" == 5? array(0) == 0? array(0,0,0) == 0? 0.0000000000000000000000000000000000000000000000000001 == array()?
Deceze

12
@ Raithlin, cuidado com a matriz. triple igual dá falsepara diferentes matrizes em javascript, mas truepara PHP desde que seus valores sejam iguais .
Pacerier

14
@ Raithlin, muitos outros truques. Em JavaScript: "000" != "00" , "000" == null, "000" == false, "0x0" == false, array() == 0, false != null, array() != null, false == "0x0", false == "000". Em PHP, é o comportamento oposto: "000" == "00" , "000" != null, "000" != false, "0x0" != false, array() != 0, false == null, array() == null, false != "0x0", false != "000".
Pacerier 07/08

239

O operador == lança entre dois tipos diferentes, se forem diferentes, enquanto o operador === realiza uma 'comparação de segurança de tipo'. Isso significa que ele só retornará true se os dois 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)

3
Nitpick: === só retornará verdadeiro se ambos os operandos são do mesmo tipo e os valores são iguais =)
gnud

1
@gnud Isso é exatamente o que ele mostrou no exemplo. Se apenas comparássemos os tipos, seria apenas chamado de "comparação de tipos".
26411 Rob Stevenson-Leggett

3
Depois de usar o PHP para 8 anos, ontem foi a primeira vez que eu fui pego em uma situação onde eu deveria ter usado ===

3
=== true se eles são iguais e têm o mesmo tipo. == true se eles são iguais. ! = true se não forem iguais. ! == true se eles não são iguais ou são iguais, mas não são do mesmo tipo.
Jeremy C

1
Além disso, usar === é um pouco mais rápido que ==, pois não precisa converter o valor antes de verificar se é igual.
clauziere

88

Uma imagem vale mais que mil palavras:

==Gráfico de igualdade PHP Double Equals :

insira a descrição da imagem aqui

===Gráfico de igualdade tripla de PHP :

insira a descrição da imagem aqui

Código fonte para criar estas imagens:

https://github.com/sentientmachine/php_equality_charts

meditação de guru

Aqueles que desejam manter sua sanidade mental não leem mais, porque nada disso fará sentido, exceto para dizer que foi assim que o fractal de insanidade do PHP foi projetado.

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

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

  5. Variáveis ​​PHP que ainda não foram declaradas são falsas, mesmo que o PHP tenha uma maneira de representar variáveis ​​indefinidas, esse recurso está desativado ==.
  6. "6" == " 6",, "4.2" == "4.20"e "133" == "0133"mas 133 != 0133. Mas "0x10" == "16"e "1e3" == "1000"expondo que a conversão corda surpresa para octal irá ocorrer tanto sem a sua instrução ou consentimento, causando um erro 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. Falso é o valor mais perigoso, porque Falso é == para a maioria das outras variáveis, derrotando principalmente seu objetivo.

Esperança:

Se você estiver usando PHP, você não usará o operador double igual, porque se você usar o triplo é igual, os únicos casos em que você deve se preocupar são NAN e números tão próximos do infinito que são convertidos no infinito. Com duplos iguais, qualquer coisa pode ser surpresa ==para qualquer coisa ou, ou pode ser lançada contra a sua vontade e !=para algo que obviamente deveria ser igual.

Qualquer lugar que você usa ==no PHP tem um cheiro ruim de código por causa dos 85 bugs nele expostos por regras implícitas de elenco que parecem projetadas por milhões de programadores programando por movimento browniano.


É realmente uma boa ideia (também segura) sempre usar iguais triplos?
precisa saber é o seguinte

3
Sim, a propriedade transitiva de triplos iguais o torna mais seguro e em escala da web.
Eric Leschinski

Como um número pode estar próximo ao infinito? [gif explodindo cérebro]
Tim

40

Em relação ao JavaScript:

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

Por exemplo, a amostra 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');
}

Voto positivo, pois parece ser exatamente a mesma situação para php.
David diz que restabelece Monica

1
@DavidThomas Não é exatamente o same.See stackoverflow.com/questions/12598407/...
xdazz

22

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

== compara objetos usando o nome do objeto e seus valores. Se dois objetos são do mesmo tipo e têm os mesmos valores de membro, $a == $bproduz true.

=== compara o ID interno do objeto. Mesmo se os membros forem iguais, $a !== $bse 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

12

Em termos mais simples:

== verifica se equivalente (somente valor)

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


equivalente vs. igual : uma analogia

1 + 1 = 2 + 0 (equivalente)

1 + 1 = 1 + 1 (o mesmo)


No PHP:

true == 1 (verdadeiro - equivalente em valor)

true === 1 (false - não é o mesmo em value && type)

  • verdadeiro é booleano
  • 1 é int

"=== verifica se o mesmo (tipo valor e&)", não exatamente verdadeiro. Dois objetos stdClass têm o mesmo tipo de 'objeto' (ou seja, usando gettype ()), mas o PHP diz que são duas coisas diferentes se você usar uma comparação estrita. Veja isso .
MAChitgarha

8

É tudo sobre tipos de dados. Tome um BOOL(verdadeiro ou falso), por exemplo:

truetambém é igual 1e falsetambém é igual0

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

$var=1;

E então compare com o ==:

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

Mas $varna verdade não é igual true, não é? Em 1vez disso, possui o valor int , que, por sua vez, é igual a true.

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 fiz

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

essa condição não seria verdadeira, como $var !== trueapenas == true(se você entende o que quero dizer).

Por que você precisaria disso?

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

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

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 == falseao verificar se uma função retorna false. Em vez disso, eles usam o !. Mas, na verdade, é 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)

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


8

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

7

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';
  }
?>

Nesse caso, a saída será 'Variáveis ​​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 compara primeiro 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.


6

Dado x = 5

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


3
$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

Tenha cuidado, porém. 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...
}

3

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

O PHP permite que você faça 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á capturada e você ficará se perguntando o que aconteceu.

No PHP, == compara valores e executa conversão de tipo, se necessário (por exemplo, a cadeia "12343sdfjskfjds" se tornará "12343" em uma comparação inteira). === irá comparar o valor AND type e retornará false 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 bem-sucedido, e é por isso que recomendam "if (function ()! == false) "para evitar erros.


1
Deve-se observar que, além desses "atalhos", sabe-se que o comportamento anormal do operador == abre brechas de segurança, por exemplo, um fórum PHP popular onde era possível definir o valor do hash da senha dos cookies como true, contornando a validação if (databasehash == cookiehash).
David

3

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.

PS

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

vs.

=== Compara os valores e tipos de dados


qual é o problema com esta resposta?
Mohit Tanwani

2

Você usaria === para testar se uma função ou variável é falsa, em vez de apenas igualar a falsa (zero ou uma sequência 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;
}

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

if ($pos == false)

ou

if (!$pos)

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


2

Quanto a quando usar um sobre o outro, considere, por exemplo, a fwrite()função em PHP.

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

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

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

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

2

PHP é uma linguagem pouco tipada. O uso do operador double equal permite uma verificação solta de uma variável.

Verificar livremente um valor permitiria que alguns valores semelhantes, mas não iguais, fossem iguais:

  • ''
  • nulo
  • falso
  • 0 0

Todos esses valores seriam iguais como iguais usando o operador double equal.


1

Variáveis ​​têm 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 ...}

O PHP precisa converter ("converter") $ var para inteiro. Nesse caso, "$ var == 1" é verdadeiro porque qualquer sequência não vazia é convertida em 1.

Ao usar ===, você verifica se o valor AND THE TYPE é igual; portanto, "$ var === 1" é falso.

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

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

Esse código está errado como se myFunction()retornasse 0, foi convertido em false e você parece ter um erro. O código correto é:

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

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


com relação a cadeias não vazias, isso não é verdade. "a" == 0 é VERDADEIRO.
nickf

1

o === operador deve comparar a igualdade exata de conteúdo, enquanto o ==operador compararia a igualdade semântica. Em particular, ele coagirá as strings a números.

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


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

Até agora, todas as respostas ignoram um problema perigoso com ===. Foi observado de passagem, mas não estressado, que inteiro e duplo são tipos diferentes, portanto, o seguinte código:

$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 eles têm tipos diferentes.

Esse é um problema desagradável, porque um programa usando === pode ser executado felizmente por anos se todos os números forem pequenos o suficiente (onde "pequeno o suficiente" 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 dobro, seu tipo será alterado "para sempre", mesmo que uma operação subsequente, ou muitas operações, possa trazê-lo de volta para um número inteiro pequeno. E fica pior. Pode se espalhar - a infecção por duplicidade pode ser transmitida para qualquer coisa que tocar, um cálculo de cada vez.

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

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

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

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


0

Existem duas diferenças entre ==e=== nas matrizes e objetos PHP que acho que não foram mencionados aqui; duas matrizes com diferentes tipos de chave e objetos.

Duas matrizes com diferentes tipos de chave

Se você possui uma matriz com uma classificação de chave e outra matriz com uma classificação de chave diferente, elas são estritamente diferentes (por exemplo, usando ===). Isso pode causar se você classificar uma matriz com chave e tentar comparar a matriz classificada com a matriz original.

Por exemplo, considere uma matriz vazia. Primeiro, tentamos enviar alguns novos índices para a matriz sem nenhum tipo especial. Um bom exemplo seria uma matriz com cadeias de caracteres como chaves. Agora, em um exemplo:

// Define an array
$arr = [];

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

Agora, temos uma matriz de chaves não classificadas (por exemplo, 'ele' veio depois de 'você'). Considere a mesma matriz, 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 uma matriz por chave usando ksort () função .

Agora você tem outra matriz com uma classificação de chave diferente da primeira. Então, vamos compará-los:

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

Nota : Pode ser óbvio, mas comparar duas matrizes diferentes usando sempre comparação estrita resulta false. No entanto, duas matrizes arbitrárias podem ser iguais usando ===ou não.

Você diria: "Essa diferença é insignificante". Então eu digo que é uma diferença e deve ser considerada e pode acontecer a qualquer momento. Como mencionado acima, a classificação de chaves em uma matriz é um bom exemplo disso.

Objetos

Lembre-se de que dois objetos diferentes nunca são 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

Nota : A atribuição de 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 .

Nota : A partir do PHP7, classes anônimas foram adicionadas. A partir dos resultados, não há diferença entre new class {}e new stdClass()nos testes acima.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.