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

Операторы сравнения, как это видно из их названия, позволяют сравнивать между собой два значения. Возможно вам будет интересно также ознакомиться с разделом Сравнение типов, в котором приведено большое количество соответствующих примеров.

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

 

Операторы сравнения
ПримерНазваниеРезультат
$a == $bРавноTRUE если $a равно $b после преобразования типов.
$a === $bТождественно равноTRUE если $a равно $b и имеет тот же тип.
$a != $bНе равноTRUE если $a не равно $b после преобразования типов.
$a <> $bНе равноTRUE если $a не равно $b после преобразования типов.
$a !== $bТождественно не равноTRUE если $a не равно $b или они разных типов.
$a < $bМеньшеTRUE если $a строго меньше $b.
$a > $bБольшеTRUE если $a строго больше $b.
$a <= $bМеньше или равноTRUE если $a меньше или равно $b.
$a >= $bБольше или равноTRUE если $a больше или равно $b.
$a <=> $bКосмический корабль (spaceship)Число типа integer меньше, больше или равное нулю, когда $a соответственно меньше, больше или равно $b. Доступно c PHP 7.

 

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


<?php
var_dump(0 == "a"); // 0 == 0 -> true
var_dump("1" == "01"); // 1 == 1 -> true
var_dump("10" == "1e1"); // 10 == 10 -> true
var_dump(100 == "1e2"); // 100 == 100 -> true

switch ("a") {
case 0:
    echo "0";
    break;
case "a": // Эта ветка никогда не будет достигнута, так как "a" уже сопоставленно с 0
    echo "a";
    break;
}
?>

 


<?php  
// Целые
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
 
// С плавающей точкой
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
 
// Строки
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
 
echo "a" <=> "aa"; // -1
echo "zz" <=> "aa"; // 1
 
// Массивы
echo [] <=> []; // 0
echo [1, 2, 3] <=> [1, 2, 3]; // 0
echo [1, 2, 3] <=> []; // 1
echo [1, 2, 3] <=> [1, 2, 1]; // 1
echo [1, 2, 3] <=> [1, 2, 4]; // -1
 
// Объекты
$a = (object) ["a" => "b"]; 
$b = (object) ["a" => "b"]; 
echo $a <=> $b; // 0
 
$a = (object) ["a" => "b"]; 
$b = (object) ["a" => "c"]; 
echo $a <=> $b; // -1
 
$a = (object) ["a" => "c"]; 
$b = (object) ["a" => "b"]; 
echo $a <=> $b; // 1
 
// сравниваются только значения
$a = (object) ["a" => "b"]; 
$b = (object) ["b" => "b"]; 
echo $a <=> $b; // 1

?>

 

Для различных типов сравнение происходит в соответствии со следующей таблицей (по порядку).

Сравнение различных типов

 

Сравнение различных типов
Тип операнда 1Тип операнда 2Результат
null или stringstringNULL преобразуется в "", числовое или лексическое сравнение
bool или nullчто угодноПреобразуется в тип bool, FALSE < TRUE
objectobjectВстроенные классы могут определять свои собственные правила сравнения, объекты разных классов не сравниваются, про сравнение объектов одного класса см. Сравнение объекта
string, resource или numberstring, resource или numberСтроки и ресурсы переводятся в числа, обычная математика
arrayarrayМассивы с меньшим числом элементов считаются меньше, если ключ из первого операнда не найден во втором операнде - массивы не могут сравниваться, иначе идет сравнение соответствующих значений (см. пример ниже)
arrayчто угоднотип array всегда больше
objectчто угоднотип object всегда больше

 

Пример #1 Сравнение boolean/null


<?php
// Логические значения и null всегда сравниваются как логические
var_dump(1 == TRUE);  // TRUE - то же, что и (bool)1 == TRUE
var_dump(0 == FALSE); // TRUE - то же, что и (bool)0 == FALSE
var_dump(100 < TRUE); // FALSE - то же, что и (bool)100 < TRUE
var_dump(-10 < FALSE);// FALSE - то же, что и (bool)-10 < FALSE
var_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool)NULL < (bool)-100 это FALSE < TRUE
?>

 

Пример #2 Алгоритм сравнения обычных массивов


<?php
// Так сравниваются массивы при сравнении стандартными операторами
function standard_array_compare($op1, $op2)
{
    if (count($op1) < count($op2)) {
        return -1; // $op1 < $op2
    } elseif (count($op1) > count($op2)) {
        return 1; // $op1 > $op2
    }
    foreach ($op1 as $key => $val) {
        if (!array_key_exists($key, $op2)) {
            return null; // не могут быть сравнимы
        } elseif ($val < $op2[$key]) {
            return -1;
        } elseif ($val > $op2[$key]) {
            return 1;
        }
    }
    return 0; // $op1 == $op2
}
?>

 

Смотрите также strcasecmp()strcmp()операторы массивов и раздел руководства Типы.

Внимание

Сравнение чисел с плавающей точкой

Из-за особого внутреннего представления типа float, не нужно проверять на равенство два числа с плавающей точкой (float).

Для более подробной информации смотрите документацию по типу float.

Тернарный оператор

Еще одним условным оператором является тернарный оператор "?:".

Пример #3 Присваивание значения по умолчанию


<?php
// Пример использования тернарного оператора
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];

// Приведенный выше код аналогичен следующему блоку с использованием if/else
if (empty($_POST['action'])) {
    $action = 'default';
} else {
    $action = $_POST['action'];
}

?>

 

Выражение (expr1) ? (expr2) : (expr3) интерпретируется как expr2, если expr1 имеет значение TRUE, или как expr3, если expr1 имеет значение FALSE.

Начиная с версии PHP 5.3 также стало возможным не писать среднюю часть тернарного оператора. Выражение expr1 ?: expr3возвращает expr1 если expr1 имеет значение TRUE и expr3 в противном случае.

Замечание

Обратите внимание, что тернарный оператор является выражением и трактуется не как переменная, а как результат выражения. Это важно знать, если вы хотите вернуть переменную по ссылке. Выражение return $var == 42 ? $a : $b; не будет работать в функции, возвращающей значение по ссылке, а в более поздних версиях PHP также будет выдано предупреждение.

Замечание:

Рекомендуется избегать "нагромождения" тернарных выражений. Поведение PHP неочевидно при использовании нескольких тернарных операторов в одном выражении:

Пример #4 Неочевидное поведение тернарного оператора


<?php
// на первый взгляд, следующий код должен вывести 'true'
echo (true?'true':false?'t':'f');

// однако, он выводит 't'
// это происходит потому, что тернарные выражения вычисляются слева направо

// это намного более очевидная версия вышеприведенного кода
echo ((true ? 'true' : false) ? 't' : 'f');

// здесь вы можете видеть, что первое выражение вычисляется в 'true', которое
// в свою очередь вычисляется в (bool)true, таким образом возвращая истинную ветвь
// второго тернарного выражения.
?>

 

Оператор объединения с null

Также, начиная с PHP 7, добавился новый оператор "??" (null coalescing).

Пример #5 Присваивание значения по умолчанию


<?php
// Пример использования оператора
$action = $_POST['action'] ?? 'default';

// Пример выше аналогичен следующему коду
if (isset($_POST['action'])) {
    $action = $_POST['action'];
} else {
    $action = 'default';
}

?>

Выражение (expr1) ?? (expr2) вычисляется так: expr2, если expr1 равен NULL и expr1 в противном случае.

На практике, этот оператор не вызывает предупреждения, если левый операнд не существует, как и isset(). Это очень полезно для ключей массива.

Замечание

Пожалуйста помните, что этот оператор является выражением, и он приравнивается к выражению, а не значению переменной. Это может быть важным, если вы хотите вернуть значение по ссылке. Выражение return $foo ?? $bar; в функции возвращающей ссылку будет не работать, а выводить предупреждение.

Замечание:

Обратите внимание, что этот оператор позволяет использовать простую вложенность:

Пример #6 Вложенный оператор null coalescing


<?php

$foo = null;
$bar = null;
$baz = 1;
$qux = 2;

echo $foo ?? $bar ?? $baz ?? $qux; // выведет 1

?>