Чем отличаются операторы сравнения PHP (== double equals) и тождества (=== triple equals)? - PullRequest
468 голосов
/ 17 сентября 2008

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

  • Как именно работает слабо == сравнение?
  • Как именно работает строгое сравнение ===?

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

Ответы [ 21 ]

590 голосов
/ 17 сентября 2008

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

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

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

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

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

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

Правила конвертации

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

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

Слабое сравнение с ==

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

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

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

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

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

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

┌─────────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬─────────┬───────┬───────┐
│         │ 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  │
└─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘
236 голосов
/ 26 февраля 2009

Оператор == осуществляет приведение между двумя разными типами, если они различаются, в то время как оператор === выполняет «безопасное сравнение типов». Это означает, что он вернет 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)
68 голосов
/ 03 ноября 2016

Картинка стоит тысячи слов:

PHP двойных равных == диаграмма равенства:

enter image description here

PHP тройных равных === Диаграмма равенства:

enter image description here

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

https://github.com/sentientmachine/php_equality_charts

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

Те, кто хочет сохранить свое здравомыслие, не читают дальше, потому что ничего из этого не имеет никакого смысла, кроме как сказать, что именно так был разработан фрактал сумасшествия в PHP.

  1. NAN != NAN, но NAN == true.
  2. == преобразует левый и правый операнды в числа, если слева - число. Так 123 == "123foo", но "123" != "123foo"
  3. Шестнадцатеричная строка в кавычках иногда является плавающей точкой, и она будет неожиданно брошена против вашей воли, вызывая ошибку во время выполнения.

  4. == не является переходным, поскольку "0"== 0 и 0 == "", но "0" != ""

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

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

  8. Когда числа достаточно велики, они == Бесконечность.

  9. Новый класс == до 1.

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

Надежда

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

Везде, где вы используете ==, в PHP дурно пахнет код из-за 85 ошибок в нем, обнаруженных неявными правилами приведения, которые, похоже, разработаны миллионами программистов, программирующих с помощью броуновского движения.

39 голосов
/ 17 сентября 2008

В отношении 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');
}
22 голосов
/ 26 февраля 2009

Дополнение к другим ответам относительно сравнения объектов:

== сравнивает объекты, используя имя объекта и его значения. Если два объекта относятся к одному типу и имеют одинаковые значения членов, $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
13 голосов
/ 19 февраля 2015

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

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

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


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

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

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


В PHP:

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

true === 1 (false - не совпадает по значению && type)

  • истина логическое значение
  • 1 - int
8 голосов
/ 18 июля 2012

Это все о типах данных. Возьмите 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, так что если вы сделали:

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

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

8 голосов
/ 14 октября 2015

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

$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
6 голосов
/ 17 августа 2009

Дано x = 5

1) Оператор: == "равно". x == 8 ложно
2) Оператор: === "точно равен" (значение и тип) x === 5 верно, x === "5" ложно

4 голосов
/ 26 августа 2016

Мало примеров

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.

приписка

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

против

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

...