strcmp()
Функция strcmp() в PHP сравнивает две строки побайтово и возвращает целое число, указывающее их относительный порядок.
Введение
strcmp() — встроенная функция PHP для побайтового сравнения двух строк («бинарно-безопасное» сравнение). Вместо того чтобы отвечать на вопрос «равны ли они?» булевым значением, она возвращает целое число, которое также указывает их относительный порядок — именно то, что нужно алгоритмам сортировки. На этой странице рассматриваются синтаксис, смысл возвращаемого значения, типичные ошибки и случаи, когда стоит использовать смежные функции.
Синтаксис
strcmp(string $string1, string $string2): intФункция принимает две строки для сравнения и возвращает int:
| Возвращаемое значение | Значение |
|---|---|
0 | Строки абсолютно равны. |
< 0 (отрицательное) | $string1 стоит перед $string2. |
> 0 (положительное) | $string1 стоит после $string2. |
Гарантируется только знак результата. Величина результата является деталью реализации (часто, но не всегда, это разность ASCII-кодов первого несовпадающего байта), поэтому всегда проверяйте знак, а не конкретное число вроде
== -1или== 1.
Сравнение чувствительно к регистру и основано на байтовых значениях. Поскольку заглавные буквы ASCII (A–Z, 65–90) идут перед строчными (a–z, 97–122), "Z" считается «меньше», чем "a".
Базовый пример
"Hello" и "World" отличаются уже с первого символа: H (72) против W (87). Так как H стоит раньше, strcmp() возвращает отрицательное число, и выполняется вторая ветка, выводящая The first string is less than the second string.
Как определяется возвращаемое значение
strcmp() проходит по обеим строкам побайтово и останавливается на первой позиции, где они различаются, возвращая знак разницы байтов. Если одна строка является префиксом другой, более короткая строка считается «меньше» более длинной.
<?php
var_dump(strcmp("apple", "apple")); // int(0) — identical
var_dump(strcmp("apple", "apples")); // negative int — "apple" is shorter (a prefix)
var_dump(strcmp("apple", "Apple")); // positive int — 'a'(97) > 'A'(65)
var_dump(strcmp("abc", "abd")); // negative int — differ at 3rd char: 'c' < 'd'Третий случай — классическая ловушка: "apple" и "Apple" не равны, потому что сравнение чувствительно к регистру.
Типичная ошибка: сравнение на равенство
strcmp() возвращает 0, когда строки совпадают, а 0 в PHP является ложным значением. Поэтому такое условие работает наоборот:
<?php
$a = "secret";
$b = "secret";
// WRONG: this block runs only when the strings are DIFFERENT
if (strcmp($a, $b)) {
echo "match"; // never printed for equal strings
}
// RIGHT: test explicitly against 0
if (strcmp($a, $b) === 0) {
echo "match"; // prints "match"
}Если нужно лишь проверить, равны ли две строки (а не их порядок), оператор === нагляднее и быстрее: $a === $b.
Сортировка с помощью strcmp()
Главное преимущество strcmp() — её роль в качестве компаратора. usort() ожидает callback, возвращающий отрицательное, нулевое или положительное значение — именно такой контракт у strcmp():
<?php
$fruits = ["banana", "Apple", "cherry", "apple"];
usort($fruits, "strcmp");
print_r($fruits);
// Array ( [0] => Apple [1] => apple [2] => banana [3] => cherry )"Apple" с заглавной буквой оказывается первым, потому что A (65) стоит перед всеми строчными буквами. Для человекочитаемой сортировки без учёта регистра используйте strcasecmp().
Связанные функции
strcasecmp()— аналогstrcmp(), но без учёта регистра.strncmp()— сравнивает только первые n байт каждой строки.strcoll()— сравнение с учётом локали (соблюдает правила сортировки текущей локали).substr_compare()— сравнивает строки начиная с заданного смещения.strpos()— поиск позиции подстроки, а не сравнение целых строк.
Резюме
strcmp() выполняет бинарно-безопасное сравнение двух строк с учётом регистра и возвращает 0, если они равны, отрицательное число, если первая строка стоит раньше, и положительное число, если позже. Всегда проверяйте знак результата (а не конкретное значение вроде -1), помните, что 0 является ложным значением и для проверки равенства нужен явный === 0, а для сравнений без учёта регистра, частичных или с учётом локали используйте strcasecmp(), strncmp() или strcoll().