Ответы:
==
и===
Разница между ==
оператором со слабым равенством и оператором со строгим ===
идентичным идентификатором в точности объяснена в руководстве :
Операторы сравнения
┌──────────┬───────────┬────────────────────────── ─────────────────────────────────┐ │ Пример │ Имя │ Результат │ ├──────────┼───────────┼────────────────────────── ─────────────────────────────────┤ A $ a == $ b │ Равен │ ИСТИНА, если $ a равно жонглированию типов. │ A $ a === $ b │ Одинаково │ ИСТИНА, если $ a равно $ b и они одного типа. │ └──────────┴───────────┴────────────────────────── ─────────────────────────────────┘
==
равное сравнениеЕсли вы используете ==
оператор или любой другой оператор сравнения, который использует слабое сравнение, например !=
, <>
или ==
, вам всегда нужно смотреть на контекст, чтобы увидеть, что, где и почему что-то преобразуется, чтобы понять, что происходит.
В качестве ссылки и примера вы можете увидеть таблицу сравнения в руководстве :
Слабые сравнения с
==
┌─────────┬───────┬───────┬───────┬───────┬─────── ┬───────┬───────┬───────┬───────┬─────────┬─────── ┬───────┐ │ │ TRUE │ FALSE │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ array () │ "php" │ "" │ ├─────────┼───────┼───────┼───────┼───────┼─────── ┼───────┼───────┼───────┼───────┼─────────┼─────── ┼───────┤ │ ИСТИНА │ ИСТИНА │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ИСТИНА │ ИСТИНА │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ИСТИНА │ │ 1 │ ИСТИНА │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ │ 0 │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ИСТИНА │ ИСТИНА │ │ -1 │ ИСТИНА, ЛОЖЬ, ЛОЖЬ, ЛОЖЬ, ИСТИНА, ЛОЖЬ, ЛОЖЬ, ИСТИНА, ЛОЖЬ, ЛОЖЬ, ЛОЖЬ, ЛОЖЬ. │ «1» │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ │ «0» │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ -1 «-1» │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ │ NULL │ FALSE │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ TRUE │ TRUE │ TRUE │ array () │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ TRUE │ FALSE │ FALSE │ Ph «php» │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ "" │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ └─────────┴───────┴───────┴───────┴───────┴─────── ┴───────┴───────┴───────┴───────┴─────────┴─────── ┴───────┘
===
одинаковое сравнениеЕсли вы используете ===
оператор или любой другой оператор сравнения, который использует строгое сравнение, такое как !==
или ===
, то вы всегда можете быть уверены, что типы не будут волшебным образом изменяться, потому что преобразование не будет происходить. Таким образом, при строгом сравнении тип и значение должны совпадать, а не только значение.
В качестве ссылки и примера вы можете увидеть таблицу сравнения в руководстве :
Строгое сравнение с
===
┌─────────┬───────┬───────┬───────┬───────┬─────── ┬───────┬───────┬───────┬───────┬─────────┬─────── ┬───────┐ │ │ TRUE │ FALSE │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ array () │ "php" │ "" │ ├─────────┼───────┼───────┼───────┼───────┼─────── ┼───────┼───────┼───────┼───────┼─────────┼─────── ┼───────┤ │ ИСТИНА │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ │ 1 │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ 0 │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ -1 │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ │ «1» │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ │ «0» │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ -1 «-1» │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ │ НУЛЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ │ array () │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ Ph «php» │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ │ «» │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ └─────────┴───────┴───────┴───────┴───────┴─────── ┴───────┴───────┴───────┴───────┴─────────┴─────── ┴───────┘
true
или false
. Это легко разыграть. Все остальные значения имеют, для всех практических целей, практически неограниченные комбинации. Есть "five" == 5
? array(0) == 0
? array(0,0,0) == 0
? 0.0000000000000000000000000000000000000000000000000001 == array()
?
false
для разных массивов в javascript, но true
для PHP, пока их значения равны .
"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"
.
Оператор == осуществляет приведение между двумя различными типами, если они различаются, а оператор === выполняет «безопасное сравнение типов». Это означает, что он вернет 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 Double Equals :===
Диаграмма равенства тройных равных PHP :Исходный код для создания этих изображений:
https://github.com/sentientmachine/php_equality_charts
Те, кто хочет сохранить свое здравомыслие, не читают дальше, потому что ничего из этого не имеет никакого смысла, кроме как сказать, что именно так был разработан фрактал безумия в PHP.
NAN != NAN
но NAN == true
. ==
преобразует левый и правый операнды в числа, если левый номер. Так 123 == "123foo"
, но"123" != "123foo"
Шестнадцатеричная строка в кавычках иногда является плавающей точкой и будет неожиданно брошена против вашей воли, вызывая ошибку во время выполнения.
==
не является переходным, потому что "0"== 0
, 0 == ""
но"0" != ""
==
."6" == " 6"
, "4.2" == "4.20"
и "133" == "0133"
но 133 != 0133
. Но "0x10" == "16"
и предоставление "1e3" == "1000"
этого неожиданного преобразования строки в восьмеричное произойдет как без вашего разрешения, так и с согласия, что приведет к ошибке во время выполнения.
False == 0
, ""
, []
И "0"
.
Когда числа достаточно велики, они == Бесконечность.
Новый класс == к 1.
Если вы используете 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
выдается значение 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
Проще говоря:
== проверяет эквивалентность (только значение)
=== проверяет, совпадает ли (значение && type)
эквивалентно или одинаково: аналогия
1 + 1 = 2 + 0 (эквивалент)
1 + 1 = 1 + 1 (то же самое)
В PHP:
true == 1 (true - эквивалент по значению)
true === 1 (false - не совпадает по значению && type)
Это все о типах данных. Возьмите BOOL
(истина или ложь), например:
true
также равно, 1
а
false
также равно0
The ==
не заботится о типах данных при сравнении: так что если у вас есть переменная, равная 1 (которая также может быть true
):
$var=1;
А затем сравните с ==
:
if ($var == true)
{
echo"var is true";
}
Но на $var
самом деле не равно true
, не так ли? 1
Вместо этого он имеет значение int , которое, в свою очередь, равно true.
С ===
помощью проверяются типы данных, чтобы убедиться, что две переменные / объекты / что угодно используют один и тот же тип.
Так что если бы я сделал
if ($var === true)
{
echo "var is true";
}
это условие не будет истинным, как $var !== true
только == true
(если вы знаете, что я имею в виду).
Зачем вам это нужно?
Просто - давайте посмотрим на одну из функций PHP array_search()
:
array_search()
Функция просто ищет значения в массиве и возвращает ключ элемента значение было найдено. Если значение не может быть найден в массиве, он возвращает ложь . Но что делать , если вы сделали значение array_search()
on, хранящееся в первом элементе массива (который будет иметь ключ массива 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)
Таким образом, для таких вещей вы должны использовать ===
вместо этого, чтобы проверить тип данных.
Одним из примеров является то, что атрибут базы данных может быть нулевым или "":
$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
php == - это оператор сравнения, который сравнивает значения переменных. Но === сравнивает значение и тип данных.
Например,
<?php
$var1 = 10;
$var2 = '10';
if($var1 == $var2) {
echo 'Variables are equal';
} else {
echo 'Variables are not equal';
}
?>
В этом случае вывод будет «Переменные равны», даже если их типы данных различны.
Но если мы будем использовать === вместо ==, результатом будет «Переменные не равны». Сначала php сравнивает значение переменной, а затем тип данных. Здесь значения одинаковы, но типы данных разные.
Данный x = 5
1) Оператор: == "равно". x == 8
ложно
2) Оператор: === "точно равно" (значение и тип) x === 5
верно, x === "5"
ложно
$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, то увидите, что многие функции возвращают «ложь» в случае сбоя функции, но они могут вернуть 0 в успешном сценарии, поэтому они рекомендуют делать «if (function ()! ==» ложно) "чтобы избежать ошибок.
Немного примеров
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.
PS
== Сравнивает только значение, он не будет беспокоиться о типах данных
против
=== Сравнивает значения и типы данных
Вы должны использовать ===, чтобы проверить, является ли функция или переменная ложной, а не просто равной ложной (ноль или пустая строка).
$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 является свободно типизированным языком. Использование оператора двойного равенства позволяет свободно проверять переменную.
Слабая проверка значения позволит некоторым подобным, но не равным, значениям равняться одному и тому же:
Все эти значения будут равны как равные, используя оператор двойного равенства.
Переменные имеют тип и значение.
Когда вы используете эти переменные (в PHP), иногда у вас нет хорошего типа. Например, если вы делаете
if ($var == 1) {... do something ...}
PHP должен конвертировать ("для приведения") $ var в целое число. В этом случае «$ var == 1» имеет значение true, потому что любая непустая строка приводится к 1.
При использовании === вы проверяете, что значение И ТИП равны, поэтому "$ var === 1" равно false.
Это полезно, например, когда у вас есть функция, которая может возвращать false (при ошибке) и 0 (результат):
if(myFunction() == false) { ... error on myFunction ... }
Этот код неверен, как будто myFunction()
возвращает 0, он приведен к ложному, и вы, кажется, есть ошибка. Правильный код:
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);
?>
Все ответы до сих пор игнорируют опасную проблему с ===. Попутно было отмечено, но не подчеркнуто, что 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()
в тестах выше.