Відповіді:
==
і===
Різниця між слабко ==
рівним оператором і суворо ===
ідентичним оператором точно роз'яснена в посібнику :
Оператори порівняння
┌─────────────────────────────────────────────────── ──────────────────────────────────┐ │ Приклад │ Ім'я │ Результат │ ├─────────────────────────────────────────────────── ──────────────────────────────────┤ │ $ a == $ b │ Дорівнює │ ІСТИНА, якщо $ a дорівнює $ b після типу жонглювання. │ │ $ a === $ b │ Ідентична │ ІСТИНА, якщо $ a дорівнює $ b, і вони одного типу. │ └─────────────────────────────────────────────────── ──────────────────────────────────┘
==
рівне порівнянняЯкщо ви використовуєте ==
оператора або будь-якого іншого оператора порівняння, який використовує слабке порівняння, наприклад !=
, <>
або ==
, вам завжди потрібно подивитися на контекст, щоб побачити, що, де і чому щось перетворюється, щоб зрозуміти, що відбувається.
В якості посилання та прикладу ви можете побачити таблицю порівняння в посібнику :
Вільні порівняння з
==
┌─────────────────────────────────────────────────── ┬─────────────────────────────────────────────────── ┬───────┐ │ │ ІСТИНА │ FALSE │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ масив () │ "php" │ "" │ ├─────────────────────────────────────────────────── ┼─────────────────────────────────────────────────── ┼───────┤ │ ІСТИНА │ ІСТИНА │ ФАЛЬСА │ ІСТИНА │ ФАЛЬСА │ ПРАВДА │ ІСТИНА AL ФАЛЬСЬКА │ ІСТИНА AL ФАЛЬСА AL ЛАЖКА UE ІСТИНА AL ФАЛЬС │ │ ФАЛЬСЬКА │ ЛУЖКА │ ПРАВДА │ ФАЛЬСА │ ІСТИНА │ ФАЛЬСА │ ЛАСКА SE ІСТИНА │ ФАЛЬСА │ ПРАВДА │ ІСТИНА │ ФАЛЬС │ ПРАВИЛЬНА │ │ 1 │ ІСТИНА │ FALSE │ ІСТИНА │ FALSE │ FALSE │ ІСТИНА │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ │ 0 │ FALSE │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ TRUE │ FALSE │ TRUE │ FALSE │ TRUE │ TRUE │ │ -1 │ ПРАВИЛЬНА │ ЛАЖКА │ ФАЛЬСА │ ФАЛЬСА │ ПРАВДА │ ФАЛЬСА │ ФАЛЬСЬКА │ ПРАВИНА AL ФАЛЬСА AL ФАЛЬСЕ AL ФАЛЬСА │ ЛАСКА │ │ "1" │ ПРАВИЛЬНА │ FALSE │ ІСТИНА │ FALSE │ FALSE │ ІСТИНА │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ │ "0" │ ЛЕЖКА │ ІСТИНА │ ЛАЖКА │ ІСТИНА │ ФАЛЬСА AL ФАЛЬСА │ ПРАВИНА │ ФАЛЬ │ ФАЛЬ │ ФАЛЬС │ ФАЛЬС │ ФАЛЬ │ │ "-1" │ ІСТИНА │ FALSE AL FALSE │ FALSE │ ІСТИНА │ FALSE │ FALSE │ ІСТИНА │ FALSE │ FALSE │ FALSE │ FALSE │ │ NULL │ FALSE │ ІСТИНА │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ TRUE │ FALSE │ TRUE │ │ масив () │ ФАЛЬ │ ІСТИНА │ ФАЛЬ │ ФАЛЬ │ ФАЛЬС │ ФАЛЬС │ ФАЛЬ │ ФАЛЬ │ ІСТИНА │ ПРАВИЛЬНА SE ФАЛЬС │ ФАЛЬС │ │ "php" │ ПРАВИЛЬНА │ ЛАЖКА │ ФАЛЬСА │ ПРАВИЛЬНА │ ЛОЖКА │ ФАЛЬСА SE ФАЛЬСА SE ФАЛЬСА SE ФАЛЬСА SE ФАЛЬСА │ ПРАВИЛЬНА │ ФАЛЬСА │ │ "" │ FALSE │ ІСТИНА │ FALSE │ ІСТИНА │ FALSE │ FALSE │ FALSE │ FALSE │ ІСТИНА │ FALSE │ FALSE │ TRUE │ └─────────────────────────────────────────────────── ┴─────────────────────────────────────────────────── ┴───────┘
===
однакове порівнянняЯкщо ви використовуєте ===
оператора або будь-якого іншого оператора порівняння, який використовує суворе порівняння, наприклад, !==
або ===
, ви завжди можете бути впевнені, що типи не будуть магічно змінюватися, оскільки перетворення не буде відбуватися. Тож при суворому порівнянні тип і значення повинні бути однаковими, а не тільки значеннями.
В якості посилання та прикладу ви можете побачити таблицю порівняння в посібнику :
Суворе порівняння з
===
┌─────────────────────────────────────────────────── ┬─────────────────────────────────────────────────── ┬───────┐ │ │ ІСТИНА │ FALSE │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ масив () │ "php" │ "" │ ├─────────────────────────────────────────────────── ┼─────────────────────────────────────────────────── ┼───────┤ │ ІСТИНА │ ПРАВИЛЬНА │ ЛАЖКА │ ФАЛЬСА │ ФАЛЬ │ ФАЛЬСА │ ФАЛЬСА │ ФАЛЬ │ ФАЛЬ │ ФАЛЬ │ ФАЛЬС │ ФАЛЬ │ ФАЛЬС │ │ ФАЛЬСЬКА │ ЛАЖКА │ ПРАВИЛЬНА │ ФАЛЬСА │ ФАЛЬСА │ ФАЛЬСА AL ФАЛЬСЬКА │ ФАЛЬСА │ ФАЛЬ │ ФАЛЬСА │ ФАЛЬСА │ ФАЛЬ │ ФАЛЬЗА │ │ 1 │ FALSE │ FALSE │ ІСТИНА │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE AL FALSE │ FALSE │ FALSE │ │ 0 │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE AL FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ │ -1 │ FALSE │ FALSE │ FALSE │ FALSE │ ІСТИНА │ FALSE AL FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ │ "1" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ ІСТИНА │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ │ "0" │ FALSE │ FALSE AL FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE AL FALSE │ FALSE │ FALSE │ │ "-1" │ FALSE │ FALSE AL FALSE │ FALSE │ FALSE AL FALSE │ FALSE │ TRUE │ FALSE AL FALSE │ FALSE │ FALSE │ │ NULL │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE SE FALSE SE FALSE │ │ масив () │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ │ "php" │ FALSE │ FALSE AL FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE AL FALSE │ FALSE │ TRUE │ FALSE │ │ "" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE AL FALSE │ FALSE UE TRUE │ └─────────────────────────────────────────────────── ┴─────────────────────────────────────────────────── ┴───────┘
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"
.
Оператор == кидає між двома різними типами, якщо вони різні, в той час як оператор === виконує "порівняння безпечного типу". Це означає, що він поверне справжній лише тоді, коли обидва операнди мають один і той же тип і однакове значення.
Приклади:
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)
Малюнок вартує тисячі слів:
==
діаграмі рівності:===
графіка рівності:Вихідний код для створення цих зображень:
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
виходить істина.
=== порівнює внутрішній ідентифікатор об'єкта. Навіть якщо члени рівні, $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:
true == 1 (вірно - еквівалент у значенні)
true === 1 (false - не однакове значення & type)
Це все про типи даних. Візьмемо BOOL
для прикладу (істинне чи помилкове):
true
також дорівнює 1
і
false
також дорівнює0
==
Чи не піклується про типах даних при порівнянні: Так що, якщо ви мали змінну , яка є 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()
значення, яке зберігалося в першому елементі масиву (який мав би ключ масиву 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 порівнює значення змінної, а потім тип даних. Тут значення однакові, але типи даних різні.
$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...
}
vs.
// 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" у цілому порівнянні). === порівняє значення AND type та поверне 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
== Порівнюючи лише значення, воно не турбуватиметься про типи даних
vs.
=== Порівняє значення та типи даних
Ви б використовували === для перевірки того, чи є функція чи змінна помилковою, а не просто прирівнюється до 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 - мова, що не вводиться. Використання оператора подвійної рівності дозволяє вільно перевірити змінну.
Помірна перевірка значення дозволила б деяким подібним, але не рівним, значенням прирівнюватись як однакові:
Усі ці значення дорівнювали б рівним за допомогою оператора подвійного рівного.
Змінні мають тип і значення.
Коли ви використовуєте ці змінні (в PHP), іноді ви не маєте гарного типу. Наприклад, якщо ви робите
if ($var == 1) {... do something ...}
PHP повинні перетворити ("на лиття") $ var в ціле число. У цьому випадку "$ var == 1" є істинним, оскільки будь-який не порожній рядок приводиться до 1.
Використовуючи ===, ви перевіряєте, що значення І ТИП рівні, тому "$ var === 1" неправдиво.
Це корисно, наприклад, коли у вас є функція, яка може повертати помилкові (помилка) та 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);
?>
Усі відповіді поки що ігнорують небезпечну проблему з ===. Мимоволі було відмічено, але не підкреслено, що цілі та подвійні є різними типами, тому наступний код:
$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()
в них.