Сравнение величин: все способы определить большее
Основы сравнения большего значения в PHP
В условных конструкциях часто требуется проверить, превышает ли одно значение другое. Язык PHP предоставляет несколько способов выполнить такое сравнение. Рассмотрим основной оператор и альтернативные варианты.
Основное решение: оператор > (больше)
Как проверить, что одно число строго больше другого?
Оператор > возвращает true, если левый операнд больше правого. Используется в любом условном выражении.
$age = 25;
if ($age > 18) {
echo "Доступ разрешён";
}
Результат:
Доступ разрешён
Типичная ошибка: Сравнение строки с числом без приведения типа. PHP неявно преобразует строку к числу, что может привести к неожиданному результату. Например, "10" > 2 вернёт true, так как строка "10" приводится к числу 10. Однако "abc" > 0 вернёт false, так как "abc" преобразуется в 0.
Как сравнить с включением равенства?
Оператор >= (больше или равно) возвращает true, если левый операнд больше или равен правому.
$score = 75;
if ($score >= 60) {
echo "Экзамен сдан";
}
Проблема: При сравнении чисел с плавающей точкой оператор >= может дать ложный результат из-за погрешности вычислений. Рекомендуется использовать эпсилон-сравнение или bccomp.
Как выполнить лексикографическое сравнение строк?
Операторы > и < работают со строками, сравнивая их посимвольно (по кодам символов).
$str1 = "apple";
$str2 = "banana";
if ($str1 > $str2) {
echo "apple больше banana";
} else {
echo "apple не больше banana";
}
apple не больше banana
Обратите внимание: если строки начинаются с числовых символов, сравнение выполняется как строковое, а не числовое. Например, "10" > "2" вернёт false, так как символ '1' меньше '2'.
Ошибка: Путаница между строковым и числовым сравнением. При использовании операторов сравнения с двумя строками, которые выглядят как числа, результат может отличаться от ожидаемого. Всегда явно приводите типы, если нужно числовое сравнение.
Как получить трёхстороннее сравнение (меньше, равно, больше)?
Начиная с PHP 7, доступен оператор космического корабля <=>. Он возвращает -1, 0 или 1.
$a = 5;
$b = 10;
$result = $a <=> $b; // -1
Примечание: Оператор <=> также работает со строками и массивами, выполняя сравнение аналогично операторам < и >.
Как сравнить строки по значению содержимого без учёта регистра?
Функции strcmp и strcasecmp возвращают отрицательное, нулевое или положительное число.
$str1 = "Hello";
$str2 = "hello";
if (strcasecmp($str1, $str2) == 0) {
echo "Строки равны без учёта регистра";
}
Как избежать ошибок при сравнении чисел с плавающей точкой?
Из-за двоичного представления чисел, прямое сравнение может дать неверный результат. Используйте допуск (epsilon).
$a = 0.1 + 0.2; // 0.30000000000000004
$b = 0.3;
$epsilon = 1e-10;
if (abs($a - $b) > $epsilon) {
echo "a больше b с учётом погрешности";
} else {
echo "a и b практически равны";
}
Расширенные примеры сравнения большего
Представленные ниже примеры демонстрируют неочевидные ситуации и специализированные приёмы работы с оператором > и альтернативами.
Пример 1: Сравнение строки с числом при наличии нечисловых символов
$values = ["10", 2, "2abc", 5];
foreach ($values as $v) {
echo "$v > 3 = " . ($v > 3 ? 'true' : 'false') . "\n";
}
10 > 3 = true 2 > 3 = false 2abc > 3 = false 5 > 3 = true
Строка "2abc" при сравнении с числом преобразуется в 2, поэтому условие ложно.
Пример 2: Сравнение с произвольной точностью с помощью bccomp
$a = '0.123456789123456789';
$b = '0.123456789123456780';
$cmp = bccomp($a, $b, 20);
if ($cmp > 0) {
echo "a больше b";
} elseif ($cmp < 0) {
echo "a меньше b";
} else {
echo "a равно b";
}
a больше b
Функция bccomp позволяет избежать погрешностей, свойственных числам с плавающей точкой.
Пример 3: Сравнение длины массивов (количества элементов)
$arr1 = [1,2,3];
$arr2 = [1,2,3,4];
if (count($arr1) > count($arr2)) {
echo "arr1 длиннее arr2";
} else {
echo "arr1 короче или равен arr2";
}
arr1 короче или равен arr2
Напрямую оператор > для массивов не применяется (выдаст предупреждение), поэтому используется функция count.
Пример 4: Сортировка по убыванию с помощью spaceship оператора
$nums = [3, 1, 5, 2];
usort($nums, function($a, $b) {
return $b <=> $a; // обратный порядок
});
print_r($nums);
Array
(
[0] => 5
[1] => 3
[2] => 2
[3] => 1
)
Spaceship оператор удобен в пользовательских функциях сортировки.
Пример 5: Сравнение строк с учётом локали (strcoll)
setlocale(LC_ALL, 'ru_RU.UTF-8');
$str1 = "ёлка";
$str2 = "ель";
$cmp = strcoll($str1, $str2);
if ($cmp > 0) {
echo "\"ёлка\" больше \"ель\"";
} elseif ($cmp < 0) {
echo "\"ёлка\" меньше \"ель\"";
} else {
echo "равны";
}
"ёлка" больше "ель"
Функция strcoll учитывает правила сортировки заданной локали.