В чем разница между == и ===?
==?===?Какие были бы полезные примеры?
@BenAubin Я понимаю, что вы хотите помочь, и это хорошо, но эти правки не улучшили ситуацию. И теперь, когда у вас есть столько репутации, ваши правки не попадут в очередь на рассмотрение, так что будьте осторожны с вашими правками.
@klutt Мои правки были преднамеренными. OP внес изменения в течение нескольких минут после исходного сообщения, в котором запрашивались как Javascript, так и PHP, поэтому многие ответы относятся к обоим языкам. Как я упоминал в примечаниях к редактированию, мои правки вернули исходный контекст.






== и ===Разница между оператором нечеткого равенства == и оператором строгого равенства === точно объясняется в руководство:
Comparison Operators
┌──────────┬───────────┬───────────────────────────────────────────────────────────┐ │ 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. │ └──────────┴───────────┴───────────────────────────────────────────────────────────┘
== равное сравнениеЕсли вы используете оператор == или любой другой оператор сравнения, который использует нечеткое сравнение, например !=, <> или ==, вам всегда нужно смотреть на контекст, чтобы увидеть, что, где и почему что-то конвертируется, чтобы понять, что происходит.
В качестве справки и примера вы можете увидеть сравнительную таблицу в руководство:
Loose comparisons with
==┌─────────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬─────────┬───────┬───────┐ │ │ 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 │ └─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘
===Если вы используете оператор === или любой другой оператор сравнения, который использует строгое сравнение, например !== или ===, то вы всегда можете быть уверены, что типы волшебно не изменятся, потому что преобразования не будет. Таким образом, при строгом сравнении тип и значение должны быть одинаковыми, а не только значение.
В качестве справки и примера вы можете увидеть сравнительную таблицу в руководство:
Strict comparisons with
===┌─────────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬─────────┬───────┬───────┐ │ │ 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 │ └─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘
Кому-нибудь еще покажется странным, что "000" == "0000"?
Возможно, строки, которые выглядят как числа, преобразуются в числа перед сравнением, если это правда, тогда 000 == 0000 имеет смысл.
Что меня всегда удивляет, так это то, что false == array () и false == 0, но array ()! = 0, поэтому false == array ()! = / == 0? это кажется мне странным.
@Pim Ну, есть еще несколько подобных случаев, например null != "0". В конце концов, вы находятся сравниваете яблоки с апельсинами, так сказать, так что это нормально. «0» на самом деле не null. Просто все они очень хорошо преобразуются в BOOL, с чем вы обычно хотите их сравнивать.
@Pim ... продолжение: Посмотрите на это так: при преобразовании в BOOL любое значение должно приходиться только на одну из двух сторон, true или false. Это легко забросить. Однако все остальные значения имеют практически неограниченные комбинации для всех практических целей. "five" == 5? array(0) == 0? array(0,0,0) == 0? 0.0000000000000000000000000000000000000000000000000001 == array()?
@ Рэйтлин, осторожно с массивом. Triple Equals дает false для разных массивов в javascript, но true для PHP, если их значения равны равный.
@Raithlin, еще много-много подводных камней. В JavaScript:"000" != "00", "000" == null, "000" == false, "0x0" == false, array() == 0, false != null, array() != null, false == "0x0", false == "000". В PHP это противоположное поведение:"000" == "00", "000" != null, "000" != false, "0x0" != false, array() != 0, false == null, array() == null, false != "0x0", false != "000".
остерегайтесь того факта, что нет ни <==, ни >==, поэтому false <= 0 будет true. php версии 5.4.27
А что насчет пустой строки ''? хотелось бы видеть это добавлено в эту удивительно полезную таблицу! :-)
Будьте внимательны. Не всегда, если a==b и a==c, значит, a==c. Например, "" == false, "0" == false, но "" != "0".
По-видимому, 0 == "#" также является true в PHP. Безумие ++.
Также обратите внимание на 1.0 !== 1
Из PHP 8 при сравнении с числовой строкой PHP 8 использует сравнение чисел. В противном случае он преобразует число в строку и использует сравнение строк. Итак, 0 == 'foobar' - это false.
Это здорово. Нечего добавить, кроме юмора. «Все мы - пыль на ветру, чувак».
Вы могли бы использовать === для проверки того, является ли функция или переменная ложной, а не просто приравнивать к 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)
что здесь не то, что вам нужно.
Что касается 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');
}
@DavidThomas: Это не совсем то же самое, см. stackoverflow.com/questions/12598407/…
Я получил этот ответ DV, потому что он пришел через 30 минут после того, как самостоятельный ответ OP подробно описал то же понимание относительно слабо типизированных сравнений. Этот ответ javascript на первоначально и в настоящее время вопрос с тегами php действительно должен быть удален, но для этого необходимо будет подсчитать количество голосов с помощью усилий сообщества. Другими словами, необходимо гораздо больше DV для того, чтобы иметь место соответствующее курирование и удалить этот ответ (удаленного пользователя).
У переменных есть тип и значение.
Когда вы используете эти переменные (в PHP), иногда у вас нет подходящего типа. Например, если вы сделаете
if ($var == 1) {... do something ...}
PHP должен преобразовать ("преобразовать") $ var в целое число. В этом случае «$ 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 ... }
потому что проверка состоит в том, что возвращаемое значение "является логическим и ложным", а не "может быть преобразовано в ложное".
что касается непустых строк, это на самом деле неправда. "a" == 0 - ИСТИНА.
Оператор == выполняет преобразование между двумя разными типами, если они различны, а оператор === выполняет «типизированное сравнение». Это означает, что он вернет истину только в том случае, если оба операнда имеют один и тот же тип и одинаковое значение.
Примеры:
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)
Nitpick: === вернет истину, только если оба операнда одного типа и значения равны =)
@gnud Это именно то, что он показал в примере. Если бы это было просто сравнение типов, это было бы просто «сравнением типов», не так ли.
После 8 лет использования PHP вчера я впервые попал в ситуацию, когда мне следовало использовать ===
=== true, если они равны и имеют одинаковый тип. == истина, если они равны. ! = истина, если они не равны. ! == true, если они не равны или равны, но не одного типа.
Кроме того, использование === немного быстрее, чем ==, поскольку не нужно преобразовывать значение перед проверкой его равенства.
остерегайтесь того факта, что нет ни <==, ни >==, поэтому false <= 0 будет true. php версии 5.4.27
Не правда. === не дает истины, даже если у вас есть точно такие же объекты, которые относятся к одному классу и имеют одинаковые значения свойств - для всех свойств.
Примечательно 1.0 !== 1
Дополнение к другим ответам, касающимся сравнения объектов:
== сравнивает объекты, используя имя объекта и их значения. Если два объекта относятся к одному типу и имеют одинаковые значения элементов, $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
Все дело в типах данных. Возьмем, к примеру, BOOL (истина или ложь):
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() просто ищет значение в массиве и возвращает ключ элемента, в котором значение было найдено. Если значение не может быть найдено в массиве, она возвращает ложный. Но что, если бы вы сделали 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)
Поэтому для подобных вещей вместо этого вы должны использовать ===, чтобы проверять тип данных.
<?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);
?>
Одна картинка стоит тысячи слов:
==:===:Исходный код для создания этих изображений:
https://github.com/sentientmachine/php_equality_charts
Те, кто хочет сохранить рассудок, не читают дальше, потому что все это не будет иметь никакого смысла, кроме как сказать, что именно так был разработан фрактал безумия PHP.
NAN != NAN, но NAN == true.
== преобразует левый и правый операнды в числа, если left является числом. Итак, 123 == "123foo", но "123" != "123foo"
Шестнадцатеричная строка в кавычках иногда является плавающей и будет неожиданно преобразована в плавающую форму против вашей воли, что вызовет ошибку времени выполнения.
== не является транзитивным, потому что "0"== 0 и 0 == "", но "0" != ""
Переменные PHP, которые еще не были объявлены, являются ложными, хотя в PHP есть способ представления неопределенных переменных, эта функция отключена в ==.
"6" == " 6", "4.2" == "4.20" и "133" == "0133", но 133 != 0133. Но "0x10" == "16" и "1e3" == "1000", демонстрирующие это неожиданное преобразование строки в восьмеричное, произойдет как без вашей инструкции, так и без вашего согласия, что приведет к ошибке времени выполнения.
False == 0, "", [] и "0".
Если вы добавляете 1 к числу, и они уже удерживают свое максимальное значение, они не переходят в цикл, вместо этого они приводятся к infinity.
Свежий класс равен == 1.
False - наиболее опасное значение, потому что False == для большинства других переменных, в основном противореча его назначению.
Если вы используете PHP, вы не должны использовать оператор двойного равенства, потому что, если вы используете тройное равенство, единственные крайние случаи, о которых следует беспокоиться, - это NAN и числа, настолько близкие к максимальному значению их типа данных, что они приводятся к бесконечности. С двойным равенством все может быть неожиданностью для == или может быть неожиданностью против вашей воли, а != - для чего-то, из чего он, очевидно, должен быть равен.
Везде, где вы используете == в PHP, это неприятный запах кода из-за 85 ошибок в нем, обнаруженных неявными правилами приведения типов, которые кажутся разработанными миллионами программистов, программирующих с помощью броуновского движения.
Действительно ли всегда использовать тройное равенство - хорошая идея (также безопасная)?
Да, транзитивное свойство тройного равенства делает его более безопасным и масштабируемым.
Как число может быть близким к бесконечности? [взрывающийся мозг gif]
В частности, 1.0 !== 1, который может быть немного подвох, например floor(4 / 3) === 1 ? 'works as might be expected' : 'what?'
@EricLeschinski floor(4/3) === 1 не имеет значения true, потому что floor возвращает float (хотя возвращаемое значение обязательно целое число, а не по типу) - отсюда и причина указать на эту ошибку. У JavaScript нет этой проблемы, потому что существует только один числовой тип (хотя из-за этого есть другие проблемы, такие как округление целых чисел).
Все ответы до сих пор игнорируют опасную проблему с ===. Попутно было отмечено, но не подчеркнуто, что 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 не эквивалентен, потому что он имеет только один числовой тип (внутри он может иметь разные побитовые представления, но не вызывает проблем для ===).
Мой совет - не используйте ни то, ни другое. Вам нужно написать свою собственную функцию сравнения, чтобы действительно исправить этот беспорядок.
Есть два различия между == и === в массивах и объектах 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().
==:В большинстве языков программирования оператор сравнения (==) проверяет, с одной стороны, тип данных, а с другой стороны, содержимое переменной на равенство. Стандартный оператор сравнения (==) в PHP ведет себя иначе. Он пытается преобразовать обе переменные в один и тот же тип данных перед сравнением и только после этого проверяет, является ли содержимое этих переменных одинаковым. Получены следующие результаты:
<?php
var_dump( 1 == 1 ); // true
var_dump( 1 == '1' ); // true
var_dump( 1 == 2 ); // false
var_dump( 1 == '2' ); // false
var_dump( 1 == true ); // true
var_dump( 1 == false ); // false
?>
===:Этот оператор также проверяет тип данных переменной и возвращает (bool) истину, только если обе переменные имеют одинаковое содержимое и один и тот же тип данных. Таким образом, будет правильным следующее:
<?php
var_dump( 1 === 1 ); // true
var_dump( 1 === '1' ); // false
var_dump( 1 === 2 ); // false
var_dump( 1 === '2' ); // false
var_dump( 1 === true ); // false
var_dump( 1 === false ); // false
?>
Подробнее в В чем разница между == и === в PHP
Разница между == (равно) и === (одинаково равно)
PHP предоставляет два оператора сравнения для проверки равенства двух значений. Основное различие между этими двумя операндами заключается в том, что '==' проверяет, соответствуют ли значения двух операндов equal or not. С другой стороны, '===' проверяет значения, а также тип операндов equal or not.
== (Equal)
=== (Identical equal)
Пример =>
<?php
$val1 = 1234;
$val2 = "1234";
var_dump($val1 == $val2);// output => bool(true)
//It checks only operands value
?>
<?php
$val1 = 1234;
$val2 = "1234";
var_dump($val1 === $val2);// output => bool(false)
//First it checks type then operands value
?>
если мы введем cast $ val2 в (int) $ val2 или (string) $ val1, тогда он вернет true
<?php
$val1 = 1234;
$val2 = "1234";
var_dump($val1 === (int)$val2);// output => bool(true)
//First it checks type then operands value
?>
ИЛИ ЖЕ
<?php
$val1 = 1234;
$val2 = "1234";
var_dump($val1 === (int)$val2);// output => bool(true)
//First it checks type then operands value
?>
@BenAubin: Серьезно, внесенные вами правки вообще ничего не улучшили.