Способы и режимы поиска данных в PHP

Раздел: PHP -> Поиск в PHP

Различные режимы поиска в PHP

Как выполнить поиск подстроки с учётом регистра и безопасно обработать отсутствие результата?

Наиболее эффективным для простого поиска точного вхождения подстроки является использование функции strpos с последующей строгой проверкой результата. В отличие от str_contains (доступна с PHP 8.0), функция strpos поддерживается во всех версиях и позволяет получить позицию вхождения, что бывает полезно.

$string = 'Привет, мир PHP!';
$search = 'PHP';
$pos = strpos($string, $search);
if ($pos !== false) {
    echo "Найдено на позиции: $pos";
} else {
    echo "Подстрока не найдена";
}

Search forum php (поиск по форуму на php)

Результат: Найдено на позиции: 13

Ошибка: Использование оператора != false без строгого сравнения (!== false) может привести к ложному срабатыванию, если подстрока найдена в позиции 0. Всегда сравнивайте с !== false.

Как найти подстроку без учёта регистра?

Для регистронезависимого поиска используется функция stripos. Она работает аналогично strpos, но игнорирует регистр символов.

$string = 'Привет, мир PHP!';
$search = 'php';
$pos = stripos($string, $search);
if ($pos !== false) {
    echo "Найдено на позиции: $pos";
} else {
    echo "Не найдено";
}

Search php browse (просмотр поиска php)

Результат: Найдено на позиции: 13

Проблема: Функция stripos не поддерживает многобайтовые кодировки по умолчанию. Для работы с UTF-8 применяется mb_stripos.

Как проверить наличие подстроки без получения позиции (PHP 8+) ?

Если нужна только проверка факта вхождения, удобно использовать str_contains. Она возвращает true или false и не требует строгой проверки позиции.

$string = 'PHP is great';
if (str_contains($string, 'PHP')) {
    echo "Содержит";
} else {
    echo "Не содержит";
}

Search php mode search (режим поиска php)

Результат: Содержит

Ограничение: Функция доступна только с PHP 8.0. В более старых версиях используйте strpos.

Как выполнить поиск по шаблону с подстановочными знаками (wildcard)?

Для поиска строк, соответствующих простым шаблонам в стиле оболочки Unix (например, *.php), применяется fnmatch. Она особенно полезна при фильтрации имён файлов.

$filename = 'index.php';
if (fnmatch('*.php', $filename)) {
    echo "Файл PHP";
} else {
    echo "Другой тип";
}

Search php images (поиск изображений в php)

Результат: Файл PHP

Особенность: Поведение fnmatch зависит от системы. На Windows поддержка может быть ограничена.

Как искать по регулярному выражению и получать дополнительные данные (позиции, флаги)?

Функция preg_match с флагом PREG_OFFSET_CAPTURE возвращает позицию найденного совпадения. Это расширяет возможности поиска.

$string = 'Цена: 250 руб.';
$pattern = '/(\d+)/';
preg_match($pattern, $string, $matches, PREG_OFFSET_CAPTURE);
if ($matches) {
    $value = $matches[1][0];
    $offset = $matches[1][1];
    echo "Найдено '$value' на позиции $offset";
} else {
    echo "Совпадений нет";
}

Catalogue php search (поиск по каталогу в php)

Результат: Найдено '250' на позиции 6

Ошибка: Если регулярное выражение написано некорректно, preg_match вернёт false, а не 0. Проверяйте результат строгим сравнением === false, а также обрабатывайте ошибки с помощью preg_last_error().

Как найти элемент в массиве по значению?

Для поиска в одномерном массиве используется array_search. Она возвращает ключ первого найденного элемента или false.

$fruits = ['apple', 'banana', 'orange'];
$key = array_search('banana', $fruits);
if ($key !== false) {
    echo "Ключ: $key";
} else {
    echo "Не найдено";
}

Search php keywords (поиск по ключевым словам в php)

Результат: Ключ: 1

Внимание: array_search работает только с одномерными массивами. Для многомерных необходима рекурсия.

Как найти файлы по шаблону в файловой системе?

Функция glob возвращает массив файлов и директорий, соответствующих шаблону. Поддерживаются подстановочные знаки.

$files = glob('*.txt');
print_r($files);

Результат: Array ( [0] => readme.txt [1] => data.txt )

Ограничение: glob не рекурсивна по умолчанию. Для рекурсивного обхода нужна комбинация с GLOB_ONLYDIR и циклом, либо использование итераторов.

- Search index php topic (поиск темы в индексе php)

Расширенные примеры поиска в PHP

Поиск в многомерном массиве с использованием рекурсивной функции

Функция array_search не работает с вложенными массивами. Рекурсивный поиск позволяет найти значение на любом уровне вложенности и вернуть путь к нему.

Пример
function recursive_array_search($needle, $haystack, $path = []) {
    foreach ($haystack as $key => $value) {
        $currentPath = array_merge($path, [$key]);
        if ($value === $needle) {
            return $currentPath;
        }
        if (is_array($value)) {
            $result = recursive_array_search($needle, $value, $currentPath);
            if ($result !== null) {
                return $result;
            }
        }
    }
    return null;
}

$data = [
    'users' => [
        ['name' => 'Иван', 'age' => 30],
        ['name' => 'Мария', 'age' => 25]
    ]
];
$path = recursive_array_search('Мария', $data);
print_r($path); // ['users', 1, 'name']
Array
(
    [0] => users
    [1] => 1
    [2] => name
)

Проблема: Глубокая рекурсия может превысить лимит стека при очень больших массивах. В таких случаях рассматривается итеративный подход с использованием SplStack.

Поиск всех вхождений подстроки с помощью preg_match_all и флагов

Флаг PREG_SET_ORDER группирует результаты по каждому совпадению, а PREG_UNMATCHED_AS_NULL заполняет отсутствующие группы значением null.

Пример
$text = 'номер1: 123, номер2: 456';
$pattern = '/(номер\d+): (\d+)/';
preg_match_all($pattern, $text, $matches, PREG_SET_ORDER | PREG_UNMATCHED_AS_NULL);
print_r($matches);
Array
(
    [0] => Array
        (
            [0] => номер1: 123
            [1] => номер1
            [2] => 123
        )
    [1] => Array
        (
            [0] => номер2: 456
            [1] => номер2
            [2] => 456
        )
)

Рекурсивный поиск файлов с использованием RecursiveDirectoryIterator

SPL-итераторы предоставляют удобный способ обхода файловой системы. Пример поиска всех файлов .php в каталоге и подкаталогах.

Пример
$iterator = new RecursiveDirectoryIterator('/path/to/project');
$filter = new RegexIterator($iterator, '/\.php$/i', RegexIterator::MATCH);
foreach ($filter as $file) {
    echo $file->getPathname() . PHP_EOL;
}
/path/to/project/index.php
/path/to/project/src/App.php
/path/to/project/vendor/autoload.php
...

Фильтр RegexIterator применяет регулярное выражение к каждому элементу, что позволяет гибко настраивать поиск.

Ошибка: По умолчанию RecursiveDirectoryIterator включает системные файлы (. и ..). Чтобы их исключить, используется флаг FilesystemIterator::SKIP_DOTS или вызов $iterator->setFlags(FilesystemIterator::SKIP_DOTS).

Использование mb_strpos для корректного поиска в многобайтовых строках

Для строк в кодировке UTF-8 стандартные strpos и stripos могут давать неверные позиции из-за многобайтового представления. Применяется mb_strpos с указанием кодировки.

Пример
$string = 'Привет, мир!';
$search = 'мир';
$pos = mb_strpos($string, $search, 0, 'UTF-8');
echo "Позиция: $pos";
Позиция: 8

Обратите внимание: позиция считается в символах, а не в байтах. Без mb_strpos результат был бы 9 (смещение на байтах).

Ошибка: Если кодировка не указана, mb_strpos использует внутреннюю кодировку (mb_internal_encoding). При несоответствии кодировок возможны ложные результаты.

Поиск с учётом нескольких шаблонов через объединение регулярных выражений

Иногда требуется найти строку, содержащую одно из нескольких слов. Регулярное выражение с альтернативой решает задачу.

Пример
$string = 'PHP и JavaScript';
$patterns = ['/PHP/', '/JavaScript/'];
foreach ($patterns as $pattern) {
    if (preg_match($pattern, $string)) {
        echo "Найдено: $pattern
";
    }
}
Найдено: /PHP/
Найдено: /JavaScript/

Для объединения в одно выражение: /PHP|JavaScript/.

Режим поиска PHP - comments

En
Search php mode search (php)