Как различаются операторы сравнения с равенством равенства (== double equals) и идентичности (=== triple equals)?

В чем разница между == и ===?

  • Как точно работает сравнение ==?
  • Как точно работает сравнение ===?

Какими будут полезные примеры?

Ответ 1

Разница между == и ===

Разница между свободным оператором == и строгим === идентичным оператором точно объясняется в manual:

Операторы сравнения

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

Незначительное == равное сравнение

Если вы используете оператор == или любой другой оператор сравнения, который использует слабое сравнение, например !=, <> или ==, вам всегда нужно искать контекст чтобы узнать, что, где и почему что-то преобразуется, чтобы понять, что происходит.

Правила преобразования

Таблица сравнения типов

В качестве ссылки и примера вы можете увидеть таблицу сравнения в manual:

Свободные сравнения с ==

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

Строгое сравнение ===

Если вы используете оператор === или любой другой оператор сравнения, который использует строгое сравнение, например !== или ===, то вы всегда можете быть уверены, что типы не будут изменяться магией, потому что не переходите. Поэтому при строгом сравнении тип и значение должны быть одинаковыми, а не только значением.

Таблица сравнения типов

В качестве ссылки и примера вы можете увидеть таблицу сравнения в manual:

Строгие сравнения с ===

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

Ответ 2

Оператор == отличает два разных типа, если они разные, а оператор === выполняет "сравнение типов". Это означает, что он вернет true только в том случае, если оба операнда имеют один и тот же тип и одно и то же значение.

Примеры:

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

Предупреждение: два экземпляра одного класса с эквивалентными членами НЕ соответствуют оператору ===. Пример:

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

Ответ 3

Изображение стоит тысячи слов:

PHP Double Equals == диаграмма равенства:

enter image description here

PHP Triple Equals === График равенства:

enter image description here

Исходный код для создания этих изображений:

https://github.com/sentientmachine/php_equality_charts

Гуру Медитации

Те, кто хочет сохранить свое здравомыслие, больше не читают.

  • '==' преобразует левый и правый операнды в числа, когда это возможно (123 == "123foo", но "123"!= "123foo"
  • Шестнадцатеричная строка в кавычках иногда является плавающей точкой и будет передана ей против вашей воли.
  • == не является транзитивным, потому что ( "0" равно == 0, а 0 - от "до", но "0"!= "")
  • "6" == "6", "4.2" == "4.20" и "133" == "0133". Но 133!= 0133, потому что 0133 - восьмеричный. Но "0x10" == "16" и "1e3" == "1000"
  • Переменные PHP, которые еще не были объявлены, являются ложными.

  • False равен 0, пустая строка и пустой массив и "0" .

  • Когда числа достаточно велики, они == Infinity.
  • NAN не имеет самого себя, но это правда.

  • Новый класс равен == 1.

  • False - самое опасное значение, потому что False является == для большинства других переменных, в основном побеждая его цель.

Надежда:

Если вы используете PHP, вы не должны использовать оператор double equals, всегда используйте тройные значения.

Ответ 4

Что касается JavaScript:

Оператор === работает так же, как и оператор ==, но требует, чтобы его операнды имели не только одно и то же значение, но и тот же тип данных.

Например, в примере ниже будет отображаться "x и y равны", но не "x и y одинаковы".

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

Ответ 5

В дополнение к другим ответам, касающимся сравнения объектов:

== сравнивает объекты, используя имя объекта и их значения. Если два объекта одного типа и имеют одинаковые значения элементов, $a == $b возвращает true.

=== сравнивает внутренний идентификатор объекта. Даже если члены равны, $a !== $b, если они не являются точно одним и тем же объектом.

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

Ответ 6

Проще говоря:

== проверяет, эквивалентен (только значение)

=== проверяет, одинаково (значение && type)



Эквивалент против того же: аналог

1 + 1 = 2 + 0 (эквивалентно)

1 + 1 = 1 + 1 (то же самое)



В PHP:

true == 1 (true - эквивалентно по значению)

true === 1 (false - не то же самое в значении && type)

  • true boolean
  • 1 int

Ответ 7

Все о типах данных. Возьмите BOOL (true или false), например:

true также равно 1 и false также равно 0

При сравнении == не учитываются типы данных: Итак, если у вас есть переменная, которая равна 1 (что также может быть true):

$var=1;

И затем сравните с ==:

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

Но $var фактически не равен true, не так ли? Вместо этого он имеет значение int 1, которое, в свою очередь, равно true.

С === проверяются типы данных, чтобы убедиться, что две переменные/объекты/все используются одним и тем же типом.

Итак, если я сделал

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

это условие не будет истинным, поскольку $var !== true это только == true (если вы знаете, что я имею в виду).

Зачем вам это нужно?

Простой - рассмотрим одну из функций PHP: array_search():

Функция array_search() просто ищет значение в массиве и возвращает ключ элемента, в котором было найдено значение. Если значение не может быть найдено в массиве, оно возвращает false. Но что, если вы сделали array_search() для значения, которое было сохранено в первом элементе массива (который имел бы ключ массива 0).... array_search() функция вернет 0... которая равна false..

Итак, если вы это сделали:

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

Итак, вы видите, как это может быть проблемой сейчас?

Большинство людей не используют == false при проверке, возвращает ли функция false. Вместо этого они используют !. Но на самом деле это точно так же, как с помощью ==false, поэтому если вы это сделали:

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

Итак, для подобных вещей вместо этого вы должны использовать ===, чтобы проверить тип данных.

Ответ 8

Один пример: атрибут базы данных может быть нулевым или "":

$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

Ответ 9

Учитывая x = 5

1) Оператор: == равен "равно". x == 8 является ложным
2) Оператор: === "точно равен" (значение и тип) x === 5 - true, x === "5" - false

Ответ 10

Несколько примеров

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.

== Сравнивает только значение, оно не будет беспокоиться о типах данных

против.

=== Сравнивает значения и типы данных

Ответ 11

Короче говоря, === работает так же, как и в большинстве других языков программирования.

PHP позволяет делать сравнения, которые на самом деле не имеют смысла. Пример:

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

В то время как это допускает некоторые интересные "ярлыки", вы должны остерегаться, поскольку функция, которая возвращает что-то, что она не должна (например, "ошибка", а не число) не попадет, и вам останется интересно, что произошло.

В PHP == сравнивает значения и при необходимости выполняет преобразование типов (например, строка "12343sdfjskfjds" станет "12343" в целочисленном сравнении). === будет сравнивать значение типа AND и вернет false, если тип не совпадает.

Если вы посмотрите в руководстве по PHP, вы увидите, что многие функции возвращают "false", если функция выходит из строя, но они могут возвращать 0 в успешном сценарии, поэтому они рекомендуют делать "if (function()! == false)", чтобы избежать ошибок.

Ответ 12

$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

Будьте осторожны. Вот пресловутая проблема.

// 'test' is found at position 0, which is interpreted as the boolean 'false'
if (strpos('testing', 'test')) {
    // code...
}

против.

// true, as strict comparison was made (0 !== false)
if (strpos('testing', 'test') !== false) {
    // code...
}

Ответ 13

Вы должны использовать === для проверки того, является ли функция или переменная ложной, а не просто приравнивается к false (ноль или пустая строка).

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

В этом случае strpos вернет 0, который будет равен false в тесте

if ($pos == false)

или

if (!$pos)

который вам не нужен.

Ответ 14

Что касается того, когда использовать один над другим, возьмите, например, функцию fwrite() в PHP.

Эта функция записывает содержимое в поток файлов. Согласно PHP, "fwrite() возвращает количество записанных байтов или FALSE при ошибке". Если вы хотите проверить, был ли вызов функции успешным, этот метод ошибочен:

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

Он может возвращать ноль (и считается успешным), и ваше состояние все равно срабатывает. Правильный путь:

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

Ответ 15

PHP - это свободно типизированный язык. Использование оператора с двойным равным допускает свободную проверку переменной.

Неправильная проверка значения позволит некоторым подобным, но не равным значениям приравнивать как одно и то же:

  • ''
  • NULL
  • ложь
  • 0

Все эти значения будут равны равным с использованием оператора с двойным равным.

Ответ 16

Переменные имеют тип и значение.

  • $var = "test" - это строка, содержащая "test"
  • $var2 = 24 - целое значение vhose равно 24.

Когда вы используете эти переменные (в PHP), иногда у вас нет хорошего типа. Например, если вы делаете

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

PHP должен преобразовать ( "to cast" ) $var в integer. В этом случае "$ var == 1" истинно, потому что любая непустая строка передается в 1.

При использовании === вы проверяете, что значение AND THE TYPE равно, поэтому "$ var === 1" является ложным.

Это полезно, например, когда у вас есть функция, которая может возвращать false (при ошибке) и 0 (результат):

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

Этот код неверен, как если бы myFunction() возвращал 0, он был добавлен в false и, похоже, у вас есть ошибка. Правильный код:

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

потому что тест состоит в том, что возвращаемое значение "является логическим и ложным", а не "может быть отправлено на false".

Ответ 17

Предполагается, что оператор === сравнивает точное соответствие содержания, а оператор == будет сравнивать семантическое равенство. В частности, он будет принуждать строки к номерам.

Равенство - обширный предмет. См. статья Википедии о равенстве.

Ответ 18

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

Ответ 19

Все ответы до сих пор игнорируют опасную проблему с ===. Было замечено попутно, но не подчеркнуто, что целые и двойные разные типы, поэтому следующий код:

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

дает:

 equal
 not equal

Обратите внимание, что это НЕ случай "ошибки округления". Два числа точно равны до последнего бита, но у них разные типы.

Это неприятная проблема, потому что программа, использующая ===, может работать счастливо в течение многих лет, если все числа достаточно малы (где "достаточно мало" зависит от оборудования и ОС, на которых вы работаете). Однако, если случайно, целое число оказывается достаточно большим, чтобы преобразовать его в double, его тип изменяется "навсегда", даже если последующая операция или многие операции могут вернуть ее к небольшому целому значению. И все хуже. Он может распространяться - двойная инфекция может передаваться по всему, что она затрагивает, по одному вычислению за раз.

В реальном мире это, вероятно, будет проблемой в программах, которые обрабатывают даты за пределами 2038 года, например. В это время отметки времени UNIX (количество секунд с 1970-01-01 00:00:00 UTC) потребуют более 32 бит, поэтому их представление "волшебным образом" переключится на двойное на некоторых системах. Поэтому, если вы вычисляете разницу между двумя моментами, вы можете закончиться за пару секунд, но как двойной, а не целочисленный результат, который возникает в 2017 году.

Я думаю, что это намного хуже, чем конверсии между строками и цифрами, потому что они тонкие. Мне очень легко отслеживать, что такое строка, и что такое число, но отслеживание количества бит в числе больше меня.

Итак, в приведенных выше ответах есть несколько хороших таблиц, но нет различия между 1 (как целое число) и 1 (тонкий двойной) и 1.0 (очевидный двойной). Кроме того, советы, которые вы всегда должны использовать === и никогда ==, невелики, потому что === иногда будет работать там, где == работает правильно. Кроме того, JavaScript не эквивалентен в этом отношении, поскольку он имеет только один тип номера (внутри него могут быть разные побитовые представления, но это не вызывает проблем для ===).

Мой совет - не используйте ни того, ни другого. Вам нужно написать свою собственную функцию сравнения, чтобы действительно исправить этот беспорядок.

Ответ 20

Есть два различия между == и === в массивах PHP и объектах, которые, я думаю, здесь не упоминались; два массива с разными ключами и объектами.

Два массива с разными типами ключей

Если у вас есть массив с сортировкой ключей и другой массив с другой сортировкой ключей, они строго различаются (например, с использованием ===). Это может произойти, если вы сортируете ключ по массиву и пытаетесь сравнить отсортированный массив с исходным.

Например, рассмотрим пустой массив. Сначала мы пытаемся добавить некоторые новые индексы в массив без какой-либо специальной сортировки. Хорошим примером будет массив со строками в качестве ключей. Теперь углубимся в пример:

// Define an array
$arr = [];

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

Теперь у нас есть массив несортированных ключей (например, "он" пришел после "вы"). Рассмотрим тот же массив, но мы отсортировали его ключи по алфавиту:

// Declare array
$alphabetArr = [];

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

Совет: Вы можете отсортировать массив по ключу с помощью функции ksort().

Теперь у вас есть другой массив с сортировкой ключей, отличной от первой. Итак, мы собираемся сравнить их:

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

Примечание: это может быть очевидно, но сравнение двух разных массивов с использованием строгого сравнения всегда приводит к false результату. Тем не менее, два произвольных массива могут быть равны, используя === или нет.

Вы скажете: "Эта разница незначительна". Тогда я говорю это различие и должно быть рассмотрено и может произойти в любое время. Как уже упоминалось выше, сортировка ключей в массиве является хорошим примером этого.

Объекты

Имейте в виду, два разных объекта никогда не бывают строго равными. Эти примеры помогут:

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

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

Примечание. Присвоение объекта другой переменной не создает копию, а создает ссылку на ту же область памяти, что и объект. Смотрите здесь.

Примечание. Начиная с PHP7, добавлены анонимные классы. Из результатов нет никакой разницы между new class {} и new stdClass() в тестах выше.

Ответ 21

php == это оператор сравнения, который сравнивает значения переменных. Но === сравнивает значение и тип данных.

Например,

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

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

В этом случае вывод будет "Переменные равны", даже если их типы данных различны.

Но если мы будем использовать === вместо ==, результатом будет "Переменные не равны". Сначала php сравнивает значение переменной, а затем тип данных. Здесь значения одинаковы, но типы данных разные.