W3docs

strcmp()

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

Введение

strcmp() — встроенная функция PHP для побайтового сравнения двух строк («бинарно-безопасное» сравнение). Вместо того чтобы отвечать на вопрос «равны ли они?» булевым значением, она возвращает целое число, которое также указывает их относительный порядок — именно то, что нужно алгоритмам сортировки. На этой странице рассматриваются синтаксис, смысл возвращаемого значения, типичные ошибки и случаи, когда стоит использовать смежные функции.

Синтаксис

strcmp(string $string1, string $string2): int

Функция принимает две строки для сравнения и возвращает int:

Возвращаемое значениеЗначение
0Строки абсолютно равны.
< 0 (отрицательное)$string1 стоит перед $string2.
> 0 (положительное)$string1 стоит после $string2.

Гарантируется только знак результата. Величина результата является деталью реализации (часто, но не всегда, это разность ASCII-кодов первого несовпадающего байта), поэтому всегда проверяйте знак, а не конкретное число вроде == -1 или == 1.

Сравнение чувствительно к регистру и основано на байтовых значениях. Поскольку заглавные буквы ASCII (AZ, 65–90) идут перед строчными (az, 97–122), "Z" считается «меньше», чем "a".

Базовый пример

php— editable, runs on the server

"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().

Практика

Практика
Что делает функция strcmp() в PHP?
Что делает функция strcmp() в PHP?
Was this page helpful?