it-swarm-ru.tech

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

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

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

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

469
nickf

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

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

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

 ┌──────────┬───────────┬───────────────────── ────────────────────────────────────────────┐ 
 │ Пример │ Имя │ Результат │ 
 ├──────────┼───────────┼──────────────────── ─────────────────────────────────────── 
 │ $ a == $ b │ Equal │ TRUE, если $ a равно $ b после жонглирования типа. │ 
 │ $ a === $ b │ Одинаково │ ИСТИНА, если $ a равно $ b и они одного типа. │ 
 └──────────┴───────────┴──────────────────── ───────────────────────────────────────┘ 

Свободно == равное сравнение

Если вы используете оператор == или любой другой оператор сравнения, который использует слабое сравнение, например !=, <> или ==, вам всегда нужно смотреть на контекст чтобы увидеть, что, где и почему что-то преобразуется, чтобы понять, что происходит.

Правила конвертации

Таблица сравнения типов

В качестве ссылки и примера вы можете увидеть таблицу сравнения в руководство :

Слабые сравнения с ==

┌─────────┬───────┬───────┬───────┬───────┬─────── ┬───────┬───────┬───────┬───────┬─────────┬─────── ┬───────┐ 
 │ │ ИСТИНА │ ЛОЖЬ │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ array () │ "php" ph "" │ 
 ├─────────┼───────┼───────┼───────┼─────── ┼───────┼───────┼───────┼───────┼───────┼───────── ┼───────┼───────┤ 
 │ ИСТИНА, ИСТИНА, ЛОЖЬ, ИСТИНА, ЛОЖЬ, ИСТИНА, ИСТИНА, ЛОЖЬ, ИСТИНА, ЛОЖЬ, ЛОЖЬ, ИСТИНА, ЛОЖЬ. .____.] │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ E │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ИСТИНА │ ИСТИНА │ ЛОЖЬ │ ИСТИНА. 
 │ 1 │ ИСТИНА │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ ЛОЖЬ │ 
 │ 0 │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ 
 │ -1 │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ 
 │ "1" │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ 
 │ "0" │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ 
 │ "-1" │ ИСТИНА │ ЛОЖЬ │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ 
 │ NULL │ FALSE │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ИСТИНА │ 
 │ массив () │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ TRUE │ FALSE │ FALSE │ 
 │ "php" │ TRUE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ 
 │ FALSE │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА. 
 └─────────────────┴──────┴─── ────┴───────┴───────┴───────┴───────┴───────┴───── ──┴───────┴─────────┴───────┴───────┘ 

Строгое === одинаковое сравнение

Если вы используете оператор === или любой другой оператор сравнения, который использует строгое сравнение, например !== или ===, то вы всегда можете быть уверены, что типы не будут магически изменяться, потому что не будет никакого преобразования. Таким образом, при строгом сравнении тип и значение должны совпадать, а не только значение.

Таблица сравнения типов

В качестве ссылки и примера вы можете увидеть таблицу сравнения в руководство :

Строгое сравнение с ===

┌─────────┬───────┬───────┬───────┬───────┬─────── ┬───────┬───────┬───────┬───────┬─────────┬─────── ┬───────┐ 
 │ │ ИСТИНА │ ЛОЖЬ │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ array () │ "php" ph "" │ 
 ├─────────┼───────┼───────┼───────┼─────── ┼───────┼───────┼───────┼───────┼───────┼───────── ┼───────┼───────┤ 
 │ ИСТИНА │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ 
 │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ E │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ 
 │ 1 │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ │ ЛОЖЬ ЛОЖЬ │ 
 │ 0 │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ 
 │ -1 │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ 
 │ "1" │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ 
 │ "0" │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ 
 │ "-1" │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ 
 │ НУЛЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ 
 │ массив () │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ TRUE │ FALSE │ FALSE │ 
 │ "php" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE. FALSE │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ЛОЖЬ │ ИСТИНА │ 
 └─────────┴─────────────┴─── ────┴───────┴───────┴───────┴───────┴───────┴───── ──┴───────┴─────────┴───────┴───────┘ 
591
nickf

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

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

PHP Double Equals == диаграмма равенства:

enter image description here

PHP Triple Equals === Диаграмма равенства:

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. Ложь является наиболее опасным значением, потому что Ложь == для большинства других переменных, в основном, в ущерб ее цели.

Надежда:

Если вы используете PHP, вы не должны использовать оператор двойного равенства, потому что если вы используете тройное равенство, единственные случаи Edge, о которых нужно беспокоиться, это NAN и числа настолько близкие к бесконечности, что они приводятся к бесконечности. При двойном равенстве все может быть неожиданным == чему-либо или или может быть неожиданно брошено против вашей воли, а != чему-то, чему оно, очевидно, должно быть равно.

Везде, где вы используете == в PHP, это неприятный запах кода из-за 85 ошибок в нем, обнаруживаемых неявными правилами приведения, которые, кажется, разработаны миллионами программистов, программирующих с помощью броуновского движения.

68
Eric Leschinski

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

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

== сравнивает объекты, используя имя объекта и его значения. Если два объекта имеют одинаковый тип и имеют одинаковые значения элементов, $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
22
soulmerge

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

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

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


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

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

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


В PHP:

true == 1 (true - эквивалент по значению)

true === 1 (false - значение отличается от типа &&)

  • истина булево
  • 1 - это int
13
silver

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

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() просто ищет значение в массиве и возвращает ключ элемента, в котором было найдено значение. Если значение не может быть найдено в массиве, возвращается false. Но что если вы сделали array_search() для значения, которое хранилось в первый элемент массива (который будет иметь ключ массива 0) .... функция array_search() вернет 0 .. . который равен ложному ..

Так что, если вы сделали:

$arr = array("name");
if (array_search("name", $arr) == false)
{
    // This would return 0 (the key of the element the val was found
    // in), but because we're using ==, we'll think the function
    // actually returned false...when it didn't.
}

Итак, вы видите, как это может быть проблемой сейчас?

Большинство людей не используют == false при проверке, возвращает ли функция false. Вместо этого они используют !. Но на самом деле это то же самое, что и использование ==false, так что если вы это сделали:

$arr = array("name");
if (!array_search("name", $arr)) // This is the same as doing (array_search("name", $arr) == false)

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

8
user849137

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

$attributeFromArray = "";
if ($attributeFromArray ==  ""){}  //true
if ($attributeFromArray === ""){}  //true
if ($attributeFromArray ==  null){}  //true
if ($attributeFromArray === null){}  //false

$attributeFromArray = null;
if ($attributeFromArray ==  ""){}  //true
if ($attributeFromArray === ""){}  //false
if ($attributeFromArray ==  null){}  //true
if ($attributeFromArray === null){}  //true
8
fico7489

Дано x = 5

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

6
Mannusanghi

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

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.

Постскриптум.

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

vs.

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

4
Mohit Tanwani

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

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

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

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

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

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

3
Christian P.
$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...
}
3
Seph

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

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

  • ""
  • ноль
  • false

Все эти значения будут равны как равные, используя оператор двойного равенства.

2
Cory Collier

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

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

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

2
Stacey Richards

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

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

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

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

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

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

Например,

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

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

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

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

2
2rahulsk

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

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

1
DavidWalley
<?php

    /**
     * Comparison of two PHP objects                         ==     ===
     * Checks for
     * 1. References                                         yes    yes
     * 2. Instances with matching attributes and its values  yes    no
     * 3. Instances with different attributes                yes    no
     **/

    // There is no need to worry about comparing visibility of property or
    // method, because it will be the same whenever an object instance is
    // created, however visibility of an object can be modified during run
    // time using ReflectionClass()
    // http://php.net/manual/en/reflectionproperty.setaccessible.php
    //
    class Foo
    {
        public $foobar = 1;

        public function createNewProperty($name, $value)
        {
            $this->{$name} = $value;
        }
    }

    class Bar
    {
    }
    // 1. Object handles or references
    // Is an object a reference to itself or a clone or totally a different object?
    //
    //   ==  true   Name of two objects are same, for example, Foo() and Foo()
    //   ==  false  Name of two objects are different, for example, Foo() and Bar()
    //   === true   ID of two objects are same, for example, 1 and 1
    //   === false  ID of two objects are different, for example, 1 and 2

    echo "1. Object handles or references (both == and    ===) <br />";

    $bar = new Foo();    // New object Foo() created
    $bar2 = new Foo();   // New object Foo() created
    $baz = clone $bar;   // Object Foo() cloned
    $qux = $bar;         // Object Foo() referenced
    $norf = new Bar();   // New object Bar() created
    echo "bar";
    var_dump($bar);
    echo "baz";
    var_dump($baz);
    echo "qux";
    var_dump($qux);
    echo "bar2";
    var_dump($bar2);
    echo "norf";
    var_dump($norf);

    // Clone: == true and === false
    echo '$bar == $bar2';
    var_dump($bar == $bar2); // true

    echo '$bar === $bar2';
    var_dump($bar === $bar2); // false

    echo '$bar == $baz';
    var_dump($bar == $baz); // true

    echo '$bar === $baz';
    var_dump($bar === $baz); // false

    // Object reference: == true and === true
    echo '$bar == $qux';
    var_dump($bar == $qux); // true

    echo '$bar === $qux';
    var_dump($bar === $qux); // true

    // Two different objects: == false and === false
    echo '$bar == $norf';
    var_dump($bar == $norf); // false

    echo '$bar === $norf';
    var_dump($bar === $norf); // false

    // 2. Instances with matching attributes and its values (only ==).
    //    What happens when objects (even in cloned object) have same
    //    attributes but varying values?

    // $foobar value is different
    echo "2. Instances with matching attributes  and its values (only ==) <br />";

    $baz->foobar = 2;
    echo '$foobar' . " value is different <br />";
    echo '$bar->foobar = ' . $bar->foobar . "<br />";
    echo '$baz->foobar = ' . $baz->foobar . "<br />";
    echo '$bar == $baz';
    var_dump($bar == $baz); // false

    // $foobar's value is the same again
    $baz->foobar = 1;
    echo '$foobar' . " value is the same again <br />";
    echo '$bar->foobar is ' . $bar->foobar . "<br />";
    echo '$baz->foobar is ' . $baz->foobar . "<br />";
    echo '$bar == $baz';
    var_dump($bar == $baz); // true

    // Changing values of properties in $qux object will change the property
    // value of $bar and evaluates true always, because $qux = &$bar.
    $qux->foobar = 2;
    echo '$foobar value of both $qux and $bar is 2, because $qux = &$bar' . "<br />";
    echo '$qux->foobar is ' . $qux->foobar . "<br />";
    echo '$bar->foobar is ' . $bar->foobar . "<br />";
    echo '$bar == $qux';
    var_dump($bar == $qux); // true

    // 3. Instances with different attributes (only ==)
    //    What happens when objects have different attributes even though
    //    one of the attributes has same value?
    echo "3. Instances with different attributes (only ==) <br />";

    // Dynamically create a property with the name in $name and value
    // in $value for baz object
    $name = 'newproperty';
    $value = null;
    $baz->createNewProperty($name, $value);
    echo '$baz->newproperty is ' . $baz->{$name};
    var_dump($baz);

    $baz->foobar = 2;
    echo '$foobar' . " value is same again <br />";
    echo '$bar->foobar is ' . $bar->foobar . "<br />";
    echo '$baz->foobar is ' . $baz->foobar . "<br />";
    echo '$bar == $baz';
    var_dump($bar == $baz); // false
    var_dump($bar);
    var_dump($baz);
?>
1
Sathish

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

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

Когда вы используете эти переменные (в 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, он преобразуется в false, и вы, похоже, имеете ошибку. Правильный код:

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

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

1
ofaurax

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

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

1
kmkaplan

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

Два массива с разными типами ключей

Если у вас есть массив с сортировкой ключей и другой массив с другой сортировкой ключей, они строго различаются (т.е. используют ===). Это может произойти, если вы отсортируете ключ по массиву и попытаетесь сравнить отсортированный массив с исходным.

Например, рассмотрим пустой массив. Сначала мы пытаемся вставить некоторые новые индексы в массив без какой-либо специальной сортировки. Хорошим примером будет массив со строками в качестве ключей. Теперь углубимся в пример:

// Define an array
$arr = [];

// Adding unsorted keys
$arr["I"] = "we";
$arr["you"] = "you";
$arr["he"] = "they";

Теперь у нас есть массив несортированных ключей (например, "он" пришел после "вы"). Рассмотрим тот же массив, но мы отсортировали его ключи по алфавиту:

// Declare array
$alphabetArr = [];

// Adding alphabetical-sorted keys
$alphabetArr["I"] = "we";
$alphabetArr["he"] = "they";
$alphabetArr["you"] = "you";

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

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

$arr == $alphabetArr; // true
$arr === $alphabetArr; // false

Примечание : это может быть очевидно, но сравнение двух разных массивов с использованием строгого сравнения всегда приводит к false. Однако два произвольных массива могут быть равны с использованием === или нет.

Вы скажете: "Эта разница незначительна". Тогда я говорю, что это различие и должно быть рассмотрено и может произойти в любое время. Как уже упоминалось выше, сортировка ключей в массиве является хорошим примером этого.

Объекты

Имейте в виду, два разных объекта никогда не бывают строго равными . Эти примеры помогут:

$stdClass1 = new stdClass();
$stdClass2 = new stdClass();
$clonedStdClass1 = clone $stdClass1;

// Comparing
$stdClass1 == $stdClass2; // true
$stdClass1 === $stdClass2; // false
$stdClass1 == $clonedStdClass1; // true
$stdClass1 === $clonedStdClass1; // false

Примечание : Присвоение объекта другой переменной не создает копию - скорее, он создает ссылку на ту же область памяти, что и объект. см. Здесь .

Примечание : Начиная с PHP7, добавлено анонимные классы . Исходя из результатов, нет разницы между new class {} и new stdClass() в тестах выше.

0
MAChitgarha