Чем отличаются операторы сравнения равенства PHP (== двойное равенство) и идентичности (=== тройное равенство)?


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

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

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

Author: Sebastian Zartner, 2008-09-17

20 answers

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

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

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

┌──────────┬───────────┬───────────────────────────────────────────────────────────┐
│ 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  │
└─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘
 566
Author: nickf, 2016-04-13 06:59:05

Оператор == выполняет приведение между двумя разными типами, если они разные, в то время как оператор === выполняет "типобезопасное сравнение". Это означает, что он вернет значение 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)
 227
Author: Patrick Glandien, 2017-03-12 21:10:07

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

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

enter image description here

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

enter image description here

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

Https://github.com/sentientmachine/php_equality_charts

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

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

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

  6. Ложь равна 0, пустая строка и пустой массив и "0".

  7. Когда числа достаточно велики, они равны == Бесконечности.
  8. НАН не == сама по себе, но это Правда.

  9. Новый класс - это == для 1.

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

Надежда:

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

 44
Author: Eric Leschinski, 2017-02-02 12:37:25

В отношении 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');
}
 37
Author: Peter Mortensen, 2016-01-03 15:41:49

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

==сравнивает объекты, используя имя объекта и их значения. Если два объекта одного типа и имеют одинаковые значения элементов, $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
 20
Author: soulmerge, 2010-08-16 08:56:00

В простейших терминах:

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

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


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

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

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


В PHP:

True== 1 (истинный эквивалент по значению)

Истинный === 1 ( false - не совпадает по значению && типу)

  • истина - это логическое
  • 1 - это int
 11
Author: silver, 2015-06-05 23:21:40

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

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

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

$var=1;

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

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

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

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

Так что, если бы я сделал

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
Author: Peter Mortensen, 2016-01-03 15:51:51

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

$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
 8
Author: fico7489, 2016-01-03 15:58:04

Учитывая x = 5

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

 6
Author: Mannusanghi, 2009-08-17 13:38:03
$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...
}
 3
Author: Seph, 2013-08-01 07:30:28

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

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

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

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

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

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

 3
Author: Christian P., 2016-01-03 15:47:09

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

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.

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

Против

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

 3
Author: Mohit Tanwani, 2016-08-26 15:55:10

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

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

Это не то, что вы здесь хотите.

 2
Author: Stacey Richards, 2008-09-17 07:07:10

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

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

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

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

if (fwrite(stuff) === FALSE)
{
    log('error!');
}
 2
Author: Mario, 2016-01-03 15:45:02

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

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

  • ''
  • ноль
  • ложь
  • 0

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

 2
Author: Cory Collier, 2016-01-27 21:34:34

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

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

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

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

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

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

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

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

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

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

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

 1
Author: ofaurax, 2008-09-17 07:42:15

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

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

 1
Author: kmkaplan, 2016-01-03 15:43:37
<?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
Author: Sathish, 2016-01-03 15:57:21

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

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

Дает:

 equal
 not equal

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

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

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

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

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

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

 0
Author: DavidWalley, 2017-05-09 16:31:39

Есть два различия между == и === в массивах и объектах 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() в тесты выше.

 0
Author: MAChitgarha, 2018-09-12 16:15:50