strpos()
Функция strpos() в PHP находит позицию первого вхождения подстроки в строке и возвращает числовой индекс или false, если подстрока не найдена.
Введение
Функция strpos() в PHP находит позицию первого вхождения подстроки внутри другой строки. Она возвращает индекс (начиная с нуля) этого вхождения или логическое значение false, если подстрока не встречается. Это одна из наиболее часто используемых строковых функций в PHP — вы обращаетесь к ней всякий раз, когда нужно выяснить: «содержит ли эта строка нужный текст, и где именно?»
В данной главе рассматриваются синтаксис, важнейшая проверка === false, параметр $offset, чувствительность к регистру, а также связанные функции, о которых следует знать.
Синтаксис
strpos(string $haystack, string $needle, int $offset = 0): int|false| Параметр | Описание |
|---|---|
$haystack | Строка, в которой выполняется поиск. |
$needle | Подстрока, которую нужно найти. |
$offset | Необязательный. Индекс символа, с которого начинается поиск. По умолчанию равен 0 (начало строки). Отрицательное значение отсчитывается с конца строки. |
Возвращаемое значение: целочисленная позиция первого совпадения (отсчёт с 0) или false, если $needle не найден.
Базовый пример
"World" начинается с индекса 6 в строке "Hello World" (H находится на индексе 0), поэтому вывод будет:
Found 'World' in 'Hello World' at position 6Ловушка === false (обязательно прочитайте)
Это самая распространённая ошибка при использовании strpos(). Когда совпадение находится в начале строки, strpos() возвращает 0 — а 0 является ложным значением в PHP. Если проверять результат нестрогим оператором, например if (!strpos(...)) или if (strpos(...) == false), допустимое совпадение на позиции 0 будет ошибочно воспринято как «не найдено».
<?php
$haystack = "php is great";
// WRONG: 0 is treated as "not found"
if (strpos($haystack, "php")) {
echo "loose: found\n";
} else {
echo "loose: not found (WRONG!)\n";
}
// RIGHT: use the strict !== operator
if (strpos($haystack, "php") !== false) {
echo "strict: found\n";
} else {
echo "strict: not found\n";
}Вывод:
loose: not found (WRONG!)
strict: foundВсегда сравнивайте результат со строгим оператором !== (или ===). Это золотое правило strpos().
Поиск начиная со смещения
Третий аргумент указывает strpos(), с какого места начинать поиск. Именно так можно найти второе (и последующие) вхождения подстроки — сначала найдите первое, затем повторите поиск, начиная сразу после него.
<?php
$text = "cat, dog, cat, bird";
$first = strpos($text, "cat"); // 0
$second = strpos($text, "cat", $first + 1); // 10
echo "first: $first\n";
echo "second: $second\n";Вывод:
first: 0
second: 10Отрицательное смещение начинает поиск с символа, отстоящего на указанное количество позиций от конца строки.
Чувствительность к регистру
strpos() чувствительна к регистру: "World" и "world" — разные иглы для поиска.
<?php
var_dump(strpos("Hello World", "world")); // bool(false)
var_dump(strpos("Hello World", "World")); // int(6)Если вам нужен поиск без учёта регистра, используйте stripos() — у неё та же сигнатура, но она игнорирует регистр букв.
Просто проверяем «содержит ли строка X?»
Если вас интересует лишь факт наличия подстроки (а не её позиция), в PHP 8.0+ есть гораздо более понятная функция str_contains(), которая возвращает обычное логическое значение и полностью избавляет от ловушки с === false:
<?php
// PHP 8.0+
var_dump(str_contains("Hello World", "World")); // bool(true)
var_dump(str_contains("Hello World", "world")); // bool(false)Используйте strpos(), когда нужна позиция; используйте str_contains(), когда достаточно ответа «да» или «нет».
Связанные функции
stripos()— версияstrpos()без учёта регистра.strrpos()— находит последнее вхождение вместо первого.strstr()— возвращает часть строки начиная с первого совпадения.substr()— извлекает фрагмент строки, зная позицию.str_replace()— заменяет все вхождения подстроки.preg_match()— поиск по шаблону, когда нужны регулярные выражения.
Заключение
strpos() возвращает позицию (начиная с нуля) первого вхождения подстроки или false, если она отсутствует. Запомните два правила, на которых чаще всего спотыкаются: всегда проверяйте результат строгим оператором !== false и используйте stripos() или str_contains(), когда нужен поиск без учёта регистра или простая логическая проверка.