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

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

Вопрос

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

  • Как именно == сравнительная работа?
  • Как именно действует строгий === сравнительная работа?

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

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

enter image description here

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

enter image description here

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

https://github.com/sentientmachine/php_equality_charts

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

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

  1. NAN != NAN но NAN == true.
  2. == преобразует левый и правый операнды в числа, если left — число.Так 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 ошибок в нем, обнаруженных неявными правилами приведения, которые, похоже, созданы миллионами программистов, программирующих по броуновскому движению.

Что касается 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');
}

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

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

=== сравнивает внутренние идентификаторы объектов.Даже если члены равны, $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

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

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

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


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

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

1 + 1 = 1 + 1 (такой же)


В PHP:

правда == 1 (истина – эквивалент по значению)

правда === 1 (ложь – не то же самое по значению && типу)

  • правда это логическое значение
  • 1 это интервал

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

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

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

$var=1;

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

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

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

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

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

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

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

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

Все просто — давайте взглянем на одну из функций PHP: array_search():

А array_search() Функция просто ищет значение в массиве и возвращает ключ элемента, в котором это значение было найдено.Если значение не найдено в массиве, возвращается значение ЛОЖЬ.Но что, если вы сделали 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)

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

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

$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

Данный x = 5

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

Немного примеров

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.

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

против.

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

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

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

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

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

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

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

Если вы заглянете в руководство по PHP, то увидите, что многие функции возвращают «false» в случае сбоя функции, но в случае успешного сценария они могут возвращать 0, поэтому они рекомендуют делать «if (function() !== 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, что будет означать ложь в тесте.

if ($pos == false)

или

if (!$pos)

это не то, что вам здесь нужно.

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

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

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

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

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

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

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

  • ''
  • нулевой
  • ЛОЖЬ
  • 0

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

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

Например,

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

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

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

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

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

  • $var = «test» — строка, содержащая «test».
  • $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 ... }

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

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

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

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

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

$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 не эквивалентен в этом отношении, поскольку он имеет только один числовой тип (внутренне он может иметь разные побитовые представления, но это не вызывает проблем для ===).

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

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

Кончик:Вы можете отсортировать массив по ключу, используя ксорт() функция.

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

$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() в тестах выше.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top