En quoi les opérateurs de comparaison d'égalité PHP (== double égal) et d'identité (=== triple égal) sont-ils différents?

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

Question

Quelle est la différence entre == et ===?

  • Comment fonctionne exactement la <=> comparaison approximative?
  • Comment fonctionne exactement la <=> comparaison stricte?

Quels seraient quelques exemples utiles?

Était-ce utile?

La solution

Différence entre == et ===

La différence entre l'opérateur égal != et approximativement <> identique est expliquée avec précision dans la section manuel :

  

Opérateurs de comparaison

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

Librement !== comparaison égale

Si vous utilisez l'opérateur <=> ou tout autre opérateur de comparaison utilisant une comparaison approximative, tel que <=>, <=> ou <=>, vous devez toujours examiner le contexte pour voir quoi, où et pourquoi quelque chose est converti pour comprendre ce qui se passe.

Règles de conversion

Tableau de comparaison des types

Comme référence et exemple, vous pouvez voir le tableau de comparaison dans le manuel :

  

Comparaisons lâches avec <=>

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

Comparaison stricte <=> identique

Si vous utilisez l'opérateur <=> ou tout autre opérateur de comparaison utilisant une comparaison stricte telle que <=> ou <=>, vous pouvez toujours être sûr que les types ne seront pas comme par magie change, car il n'y aura pas de conversion en cours. Donc, avec une comparaison stricte, le type et la valeur doivent être identiques, pas seulement la valeur.

Tableau de comparaison des types

Comme référence et exemple, vous pouvez voir le tableau de comparaison dans le manuel :

  

Comparaisons strictes avec <=>

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

Autres conseils

L'opérateur == effectue un basculement entre deux types différents s'ils sont différents, tandis que l'opérateur === effectue une "comparaison entre typesafe". Cela signifie qu'il ne renverra true que si les deux opérandes ont le même type et la même valeur.

Exemples:

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

Avertissement : deux instances de la même classe avec des membres équivalents ne correspondent pas à l'opérateur ===. Exemple:

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

Une image vaut mille mots:

PHP Double Equals == tableau d'égalité:

 entrez la description de l'image ici

PHP Triple est égal à === tableau d'égalité:

 entrez la description de l'image ici

Code source pour créer ces images:

https://github.com/sentientmachine/php_equality_charts

Méditation Guru

Ceux qui souhaitent garder leur santé mentale ne lisent plus parce que cela n’a aucun sens, sauf pour dire que c’est ainsi que la folie-fractale de PHP a été conçue.

  1. NAN != NAN mais NAN == true.
  2. 123 == "123foo" convertira les opérandes gauche et droit en nombres si left est un nombre. Donc "123" != "123foo", mais "0"== 0
  3. Une chaîne hexadécimale entre guillemets est parfois un float et sera un casting surprise flottant contre votre volonté, ce qui provoquera une erreur d'exécution.

  4. 0 == "" n'est pas transitif car "0" != "" et "6" == " 6" mais "4.2" == "4.20"

  5. Les variables PHP qui n'ont pas encore été déclarées sont fausses, même si PHP a un moyen de représenter des variables non définies, cette fonctionnalité est désactivée avec "133" == "0133".
  6. 133 != 0133, "0x10" == "16" et "1e3" == "1000" mais False == 0. Mais "" et [] l'exposition de cette conversion de chaîne surprise en octal se produiront toutes deux sans votre instruction ou votre consentement, ce qui provoquera une erreur d'exécution.

  7. "0", !=, <=> et <=>.

  8. Quand les nombres sont assez gros, ils sont == Infini.

  9. Une nouvelle classe est == à 1.

  10. False est la valeur la plus dangereuse, car False correspond à == à la plupart des autres variables, ce qui est en grande partie contraire à son objectif.

Espoir:

Si vous utilisez PHP, vous n’utiliserez pas l’opérateur double égal, car si vous utilisez triple égal, les seuls cas à prendre en compte sont les NAN et les nombres si proches de l’infini qu’ils sont convertis à l’infini. Avec un double égal, tout peut surprendre <=> n'importe quoi ou peut être surpris contre votre volonté et <=> de quelque chose dont il devrait évidemment être égal.

N'importe où vous utilisez <=> en PHP une mauvaise odeur de code en raison des 85 bogues qu'il contient, exposés par des règles de casting implicites qui semblent conçues par des millions de programmeurs programmant par mouvement brownien.

En ce qui concerne JavaScript:

L'opérateur === fonctionne de la même manière que l'opérateur ==, mais il nécessite que ses opérandes aient non seulement la même valeur, mais également le même type de données.

Par exemple, l'exemple ci-dessous affiche "x et y sont égaux", mais pas "x et y sont identiques".

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 ajout aux autres réponses concernant la comparaison d'objets:

== compare les objets en utilisant le nom de l'objet et leurs valeurs. Si deux objets sont du même type et ont les mêmes valeurs de membre, $a == $b renvoie true.

=== compare l'ID d'objet interne des objets. Même si les membres sont égaux, $a !== $b s’ils ne sont pas exactement le même objet.

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

En termes simples:

== vérifie si équivalent (valeur uniquement)

=== vérifie si le même (valeur & amp; & amp; type)


Équivalent ou identique: une analogie

1 + 1 = 2 + 0 (équivalent)

1 + 1 = 1 + 1 (identique)


En PHP:

true == 1 (true - valeur équivalente)

true === 1 (false - la valeur n'est pas la même & amp; & amp; type)

  • true est booléen
  • 1 est int

Tout dépend des types de données. Prenez un BOOL (vrai ou faux), par exemple:

true est également égal à 1 et false est également égal à 0

Le == ne se soucie pas des types de données lors de la comparaison: Donc, si vous aviez une variable qui est 1 (qui pourrait aussi être $var=1;):

$var

Et comparez ensuite avec le ===:

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

Mais $var !== true ne correspond pas réellement à == true, n'est-ce pas? Il a la valeur int array_search() à la place, qui à son tour est égal à true.

Avec == false, les types de données sont vérifiés pour s'assurer que les deux variables / objets / peu importe utilisent le même type.

Donc si je le faisais

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

cette condition ne serait pas vraie, car ! seulement ==false (si vous voyez ce que je veux dire).

Pourquoi en auriez-vous besoin?

Simple - jetons un coup d'œil à l'une des fonctions de PHP: <=>:

La fonction <=> recherche simplement une valeur dans un tableau et renvoie la clé de l'élément dans lequel la valeur a été trouvée. Si la valeur est introuvable dans le tableau, elle renvoie false . Mais que se passe-t-il si vous faites une <=> valeur sur une valeur qui est stockée dans le premier élément du tableau (qui aurait la clé de tableau <=>) .... le <=> la fonction renverrait 0 ... ce qui est égal à faux ..

Donc si vous l'avez fait:

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

Alors, voyez-vous comment cela pourrait être un problème maintenant?

La plupart des gens n'utilisent pas <=> pour vérifier si une fonction renvoie false. Au lieu de cela, ils utilisent le <=>. Mais en réalité, c’est exactement la même chose que d’utiliser <=>, donc si vous le faisiez:

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

Donc, pour des choses comme ça, vous utiliseriez plutôt le <=>, afin que le type de données soit vérifié.

Un exemple est qu'un attribut de base de données peut être null 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

Étant donné x = 5

1) Opérateur: == est " égal à " ;. x == 8 est faux
2) Opérateur: === est & Quot; exactement égal à & Quot; (valeur et type) x === 5 est vrai, x === "5" est faux

Quelques exemples

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.

  

== Ne compare que la valeur, sans se soucier des types de données

vs.

  

=== Compare les valeurs et les types de données

$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

Attention cependant. Voici un problème notoire.

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

En bref, === fonctionne de la même manière que == dans la plupart des autres langages de programmation.

PHP vous permet de faire des comparaisons qui n’ont pas vraiment de sens. Exemple:

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

Bien que cela permette quelques " raccourcis & "; Méfiez-vous, car une fonction qui retourne quelque chose qu'elle ne devrait pas (comme & "erreur &"; au lieu d'un nombre) ne sera pas interceptée et vous laissera se demander ce qui s'est passé.

En PHP, == compare les valeurs et effectue la conversion de type si nécessaire (par exemple, la chaîne & "12343sdfjskfjds &" deviendra & "12343 &" dans une comparaison d'entiers ). === comparera la valeur AND type et renverra false si le type n'est pas le même.

Si vous regardez dans le manuel PHP, vous verrez que beaucoup de fonctions retournent " false " si la fonction échoue, mais qu'ils peuvent renvoyer 0 dans un scénario réussi, c'est pourquoi ils recommandent d'utiliser & "if (function ()! == false) &"; pour éviter les erreurs.

Vous utiliseriez === pour vérifier si une fonction ou une variable est fausse plutôt que de simplement l'égaler à faux (zéro ou une chaîne vide).

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

Dans ce cas, strpos renverrait 0, ce qui équivaudrait à faux dans le test

if ($pos == false)

ou

if (!$pos)

ce qui n'est pas ce que vous voulez ici.

Quant à savoir quand utiliser l'un sur l'autre, prenons par exemple la fonction fwrite() en PHP.

Cette fonction écrit le contenu dans un flux de fichiers. Selon PHP, & Quot; <=> renvoie le nombre d'octets écrits, ou FALSE si une erreur survient. & Quot ;. Si vous voulez vérifier si l'appel de la fonction a réussi, cette méthode est incorrecte:

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

Il peut renvoyer zéro (et est considéré comme ayant réussi) et votre état est toujours déclenché. La bonne façon serait:

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

PHP est un langage mal typé. L’utilisation de l’opérateur double égal permet une vérification lâche d’une variable.

En vérifiant vaguement une valeur, certaines valeurs similaires, mais non égales, seraient identiques:

  • ''
  • null
  • faux
  • 0

Toutes ces valeurs équivaudraient à égales en utilisant l'opérateur double égal.

php == est un opérateur de comparaison qui compare la valeur des variables. Mais === compare la valeur et le type de données.

Par exemple,

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

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

Dans ce cas, le résultat sera "Les variables sont égales", même si leurs types de données sont différents.

Mais si nous utilisons === au lieu de ==, le résultat sera «Les variables ne sont pas égales». Le php compare d'abord la valeur de la variable puis le type de données. Ici, les valeurs sont les mêmes, mais les types de données sont différents.

Les variables ont un type et une valeur.

  • $ var = " test " est une chaîne contenant & "test &";
  • $ var2 = 24 est un entier dont la valeur est 24.

Lorsque vous utilisez ces variables (en PHP), vous n’avez parfois pas le bon type. Par exemple, si vous faites

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

PHP doit convertir (" convertir ") $ var en entier. Dans ce cas, & Quot; $ var == 1 & Quot; est vrai car toute chaîne non vide est convertie en 1.

En utilisant ===, vous vérifiez que la valeur ET LE TYPE sont égaux, donc " $ var === 1 " est faux.

Ceci est utile, par exemple, lorsque vous avez une fonction qui peut renvoyer false (en cas d'erreur) et 0 (résultat):

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

Ce code est erroné car si myFunction() renvoie 0, il est converti en false et vous semblez avoir une erreur. Le code correct est:

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

parce que le test est que la valeur de retour & "est un booléen et est faux &"; et pas & "; peut être jeté à faux &";

L’opérateur === est supposé comparer l’égalité de contenu exacte , tandis que l’opérateur == comparerait l’égalité sémantique. En particulier, il contraindra les chaînes de caractères aux nombres.

L’égalité est un vaste sujet. Voir l'article de Wikipedia sur l'égalité .

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

Toutes les réponses à ce jour ignorent un problème dangereux avec ===. Il a été noté en passant, mais pas souligné, que integer et double sont des types différents, donc le code suivant:

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

donne:

 equal
 not equal

Notez qu'il ne s'agit PAS d'une & erreur d'arrondi & ";. Les deux nombres sont exactement égaux jusqu'au dernier bit, mais ils ont des types différents.

C’est un problème désagréable, car un programme utilisant === peut fonctionner sans problème pendant des années si tous les nombres sont suffisamment petits (où & "assez petit &" dépend du matériel et du système d’exploitation utilisés). courir sur). Toutefois, si, par hasard, un nombre entier est suffisamment grand pour être converti en un double, son type est modifié & "Toujours"! même si une opération ultérieure, ou de nombreuses opérations, peut la ramener à un petit entier en valeur. Et ça empire. Elle peut se propager - l'infection à double infection peut être transmise à tout ce qu'elle touche, calcul par calcul.

Dans le monde réel, cela posera probablement un problème dans les programmes gérant des dates postérieures à 2038, par exemple. À ce stade, les horodatages UNIX (nombre de secondes depuis le 1970-01-01 à 00:00:00 UTC) nécessitent plus de 32 bits. Par conséquent, leur représentation sera & "Magiquement &"; passer à double sur certains systèmes. Par conséquent, si vous calculez la différence entre deux fois, vous risquez de vous retrouver avec quelques secondes, mais sous la forme d'un double, plutôt que le résultat entier de l'année 2017.

Je pense que c'est bien pire que les conversions entre chaînes et nombres, car c'est subtil. Je trouve facile de garder une trace de ce qui est une chaîne et de ce qui est un nombre, mais garder une trace du nombre de bits dans un nombre ne me dépasse pas.

Donc, dans les réponses ci-dessus, il y a quelques beaux tableaux, mais aucune distinction entre 1 (en tant qu'entier) et 1 (double subtil) et 1,0 (double évident). En outre, les conseils que vous devez toujours utiliser === et jamais == ne sont pas intéressants, car === échouera parfois où == fonctionne correctement. De plus, JavaScript n’est pas équivalent à cet égard car il n’a qu’un seul type de numéro (en interne, il peut avoir différentes représentations bit par bit, mais il ne pose pas de problème pour ===).

Mon conseil - n'utilisez ni l'un ni l'autre. Vous devez écrire votre propre fonction de comparaison pour vraiment réparer ce gâchis.

Il existe deux différences entre == et === dans les tableaux et les objets PHP que je pense ne pas mentionner ici; deux tableaux avec des tris de clés et des objets différents.

Deux tableaux avec différentes sortes de clés

Si vous avez un tableau avec une sorte de clé et un autre avec une sorte de clé différente, ils sont strictement différents (c'est-à-dire en utilisant false). Cela peut causer si vous triez un tableau par clé et essayez de comparer le tableau trié avec le tableau d'origine.

Par exemple, considérons un tableau vide. Premièrement, nous essayons de placer de nouveaux index dans le tableau sans aucun tri particulier. Un bon exemple serait un tableau avec des chaînes comme clés. Profondément dans un exemple:

// Define an array
$arr = [];

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

Nous avons maintenant un tableau de clés non triées (par exemple, "il" est venu après "vous"). Considérez le même tableau, mais nous avons trié ses clés par ordre alphabétique:

// Declare array
$alphabetArr = [];

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

Conseil : vous pouvez trier un tableau à l'aide de ksort () fonction.

Vous avez maintenant un autre tableau avec un type de clé différent du premier. Donc, nous allons les comparer:

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

Remarque : cela peut paraître évident, mais la comparaison de deux tableaux différents à l'aide d'une comparaison stricte donne toujours des résultats new class {}. Cependant, deux tableaux arbitraires peuvent être égaux avec new stdClass() ou non.

Vous diriez: & "Cette différence est négligeable &". Ensuite, je dis que c'est une différence et doit être pris en compte et peut se produire à tout moment. Comme mentionné ci-dessus, le tri des clés dans un tableau en est un bon exemple.

Objets

N'oubliez pas que deux objets différents ne sont jamais égaux stricto sensu . Ces exemples aideraient:

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

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

Remarque : l'attribution d'un objet à une autre variable ne crée pas de copie. Elle crée plutôt une référence au même emplacement mémoire que l'objet. Voir ici .

Remarque : à partir de PHP7, anonymous classes a été ajouté. D'après les résultats, il n'y a pas de différence entre <=> et <=> dans les tests ci-dessus.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top