strncmp()
Функция strncmp() в PHP сравнивает первые N символов двух строк с учётом регистра и возвращает целое число.
Введение
Функция strncmp() в PHP выполняет бинарно-безопасное, регистрозависимое сравнение первых N символов двух строк. Вместо полного сравнения строк она смотрит только на указанный вами начальный фрагмент — это делает её идеальным инструментом, когда вас интересует префикс, а не всё значение целиком (например, чтобы проверить, начинается ли URL с https, или сгруппировать коды, имеющие общий заголовок).
В этой статье описывается синтаксис strncmp(), способы интерпретации возвращаемого значения, несколько практических примеров, а также типичные ошибки, с которыми сталкиваются разработчики.
Синтаксис
strncmp(string $string1, string $string2, int $length): int| Параметр | Описание |
|---|---|
$string1 | Первая строка для сравнения. |
$string2 | Вторая строка для сравнения. |
$length | Максимальное количество символов от начала каждой строки для сравнения. |
strncmp() сравнивает первые $length символов $string1 и $string2 побайтово и возвращает целое число:
| Возвращаемое значение | Значение |
|---|---|
< 0 (отрицательное) | $string1 «меньше» $string2 в сравниваемом диапазоне. |
0 | Первые $length символов равны. |
> 0 (положительное) | $string1 «больше» $string2 в сравниваемом диапазоне. |
Сравнение является лексикографическим и основано на байтовых значениях символов. Поскольку заглавные буквы ASCII (A–Z, коды 65–90) идут перед строчными (a–z, коды 97–122), строка "Apple" считается меньше, чем "apple". Конкретное ненулевое число — это разница байтовых значений первых отличающихся символов, но опираться следует только на его знак, а не на величину.
Пример: сравнение префикса
<?php
$string1 = "Hello World";
$string2 = "Hello";
$length = 5;
$result = strncmp($string1, $string2, $length);
if ($result < 0) {
echo "The first $length characters of $string1 are less than the first $length characters of $string2";
} elseif ($result > 0) {
echo "The first $length characters of $string1 are greater than the first $length characters of $string2";
} else {
echo "The first $length characters of $string1 are equal to the first $length characters of $string2";
}Несмотря на то что "Hello World" и "Hello" в целом отличаются, их первые 5 символов ("Hello") идентичны, поэтому strncmp() возвращает 0 и вывод будет следующим:
The first 5 characters of Hello World are equal to the first 5 characters of HelloПример: проверка начала строки с заданного префикса
Классическое применение strncmp() — проверка наличия префикса. Передав длину префикса в качестве $length, вы сравниваете исходную строку ровно настолько, сколько занимает префикс:
<?php
$url = "https://www.w3docs.com";
if (strncmp($url, "https", 5) === 0) {
echo "Secure URL";
} else {
echo "Not secure";
}Этот код выводит Secure URL. В PHP 8.0+ встроенная функция str_starts_with() выражает то же намерение более наглядно, однако strncmp() остаётся универсальным вариантом для более старых версий.
Пример: учёт регистра
strncmp() различает верхний и нижний регистр:
<?php
echo strncmp("PHP", "php", 3); // negative: 'P' (80) < 'p' (112)Если вам нужно игнорировать регистр, используйте strncasecmp() — она выполняет то же сравнение с ограничением по длине, но без учёта регистра.
Типичные ошибки
- Значим только знак результата. Интерпретируйте результат как «отрицательное / ноль / положительное» и используйте
=== 0, когда хотите проверить совпадение префиксов. Не рассчитывайте, что значение будет ровно-1,0или1— оно может быть любым целым числом. $lengthбольше длины строк — это допустимо. Если$lengthпревышает длину любой из строк,strncmp()просто сравнивает до конца более короткой.strncmp("Hi", "Hi", 50)возвращает0.- Отрицательный
$lengthвызываетValueErrorв PHP 8.0+ (а в более старых версиях трактовался как0). - Функция работает побайтово, а не с многобайтовыми символами. Для текста в UTF-8
$lengthсчитает байты, а не символы, поэтому многобайтовый символ может оказаться разрезан. На обычных ASCII-данных это не сказывается.
Связанные функции
strcmp()— сравнивает две строки целиком с учётом регистра.strncasecmp()— аналогstrncmp(), но без учёта регистра.strcasecmp()— сравнение полных строк без учёта регистра.substr_compare()— сравнивает строки начиная с заданного смещения.strpos()— ищет позицию подстроки.
Заключение
strncmp() сравнивает только первые N символов двух строк с учётом регистра и побайтово, возвращая отрицательное число, 0 или положительное число. Используйте её, когда нужно сопоставить префикс или сравнить фиксированную начальную часть двух строк — и не забывайте проверять знак результата с помощью === 0, < 0 или > 0, а не конкретное значение.