W3docs

substr_compare()

Функция substr_compare() в PHP сравнивает части двух строк начиная с указанной позиции и до заданной длины.

Введение

Функция substr_compare() сравнивает часть одной строки с другой строкой, начиная с заданного смещения. Это аналог сравнения подстроки $main_str с $str — но без предварительного вызова substr() для извлечения подстроки. Это делает её идиоматичным и не требующим выделения памяти способом ответить на вопросы вроде «начинается ли эта строка с X?» или «заканчивается ли эта строка на Y?» в старых версиях PHP.

В этой главе объясняются параметры функции, смысл возвращаемого значения и распространённые паттерны (проверка префикса, суффикса, сравнение без учёта регистра), в которых substr_compare() особенно удобна.

Синтаксис

substr_compare(
    string $haystack,
    string $needle,
    int $offset,
    ?int $length = null,
    bool $case_insensitive = false
): int

Примечание: Параметр $length является необязательным. В PHP 8+ он явно объявлен как nullable (?int); передача null (или пропуск параметра) означает сравнение до конца $haystack.

ПараметрОписание
$haystackОсновная строка. Сравнение читает часть этой строки.
$needleСтрока, сравниваемая с частью $haystack.
$offsetПозиция в $haystack, с которой начинается сравнение. Отрицательное значение отсчитывается с конца $haystack.
$lengthКоличество символов для сравнения. Если null, используется наибольшее из оставшейся части $haystack и всей строки $needle.
$case_insensitiveЕсли true, регистр букв игнорируется ("A" равно "a"). По умолчанию false.

Возвращаемое значение

substr_compare() возвращает значение типа int:

  • 0 — сравниваемые части равны.
  • отрицательное число — часть $haystack меньше $needle (идёт раньше при сортировке).
  • положительное число — часть $haystack больше $needle (идёт позже при сортировке).

Важен знак результата; конкретная величина зависит от реализации и не должна использоваться как надёжный ориентир. Для проверки равенства сравнивайте явно с 0: substr_compare(...) === 0.

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

php— editable, runs on the server

Здесь мы сравниваем первые strlen($string2) (6) символов строки "Hello World!" со строкой "Hello!". Шестой символ — пробел (" ") в первой строке и восклицательный знак ("!") во второй; пробел (ASCII 32) стоит перед ! (ASCII 33), поэтому функция возвращает отрицательное целое число (-1).

Проверка того, начинается ли строка с префикса

Сравнение при смещении 0 с $length, равной длине префикса, является чистым тестом «начинается с»:

<?php

function startsWith(string $haystack, string $prefix): bool
{
    return substr_compare($haystack, $prefix, 0, strlen($prefix)) === 0;
}

var_dump(startsWith("php-fpm", "php"));   // bool(true)
var_dump(startsWith("python", "php"));    // bool(false)

В PHP 8.0+ можно использовать встроенную функцию str_starts_with(). substr_compare() остаётся полезной на старых версиях и когда требуется нечувствительность к регистру.

Проверка того, заканчивается ли строка на суффикс

Отрицательное смещение отсчитывается с конца строки, что делает проверки «заканчивается на» простыми — вам не нужно вычислять позицию вручную:

<?php

function endsWith(string $haystack, string $suffix): bool
{
    return substr_compare($haystack, $suffix, -strlen($suffix)) === 0;
}

var_dump(endsWith("report.pdf", ".pdf"));  // bool(true)
var_dump(endsWith("report.txt", ".pdf"));  // bool(false)

Сравнение без учёта регистра

Передайте пятым аргументом true, чтобы игнорировать регистр букв:

<?php

$sensitive   = substr_compare("Hello", "hello", 0);
$insensitive = substr_compare("Hello", "hello", 0, null, true);

echo $sensitive;    // non-zero: 'H' and 'h' differ
echo PHP_EOL;
echo $insensitive;  // 0: equal when case is ignored

Подводные камни

  • Смещение за пределами диапазона. Положительное $offset, превышающее длину $haystack, вызывает ValueError в PHP 8+ (в PHP 7 — предупреждение с возвратом false). Проверяйте смещения относительно strlen($haystack), когда они поступают из пользовательского ввода.
  • $length больше, чем осталось. Если $length превышает количество доступных символов, сравниваются только доступные символы — функция не выдаёт ошибку, просто сравнивает меньше.
  • Побайтовый режим, не многобайтовый. substr_compare() работает с байтами. Для текста в UTF-8, где один символ может занимать несколько байт, смещения и длины являются байтовыми, а не символьными.

Связанные функции

  • strcmp() — бинарно-безопасное сравнение двух строк целиком.
  • strncmp() — сравнивает только первые n символов двух строк.
  • strcasecmp() — сравнение двух строк целиком без учёта регистра.
  • substr() — извлечение части строки.

Заключение

substr_compare() сравнивает часть одной строки с другой без её предварительного извлечения, что делает функцию эффективной для проверки префиксов и суффиксов. Не забывайте сравнивать результат с 0 для проверки равенства, использовать отрицательное $offset для проверок «заканчивается на» и передавать true последним аргументом, когда регистр следует игнорировать.

Практика

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