Организация поискового просмотра на PHP

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

Поиск с возможностью просмотра результатов - одна из ключевых функций веб-приложений. В PHP реализуется разными способами: от простого перебора массивов до полнотекстового поиска в базах данных. В статье рассмотрены основные подходы, их преимущества и типичные ошибки.

Реализация поиска на PHP с просмотром результатов

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

Наиболее эффективное решение для небольших проектов - запрос SELECT ... WHERE поле LIKE '%запрос%' с пагинацией. Используется PDO для безопасности и LIMIT с OFFSET.

// Подключение к БД (PDO)
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$search = '%' . $_GET['q'] . '%';
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$perPage = 10;
$offset = ($page - 1) * $perPage;

// Подсчет общего количества
$countStmt = $pdo->prepare("SELECT COUNT(*) FROM articles WHERE title LIKE :q");
$countStmt->execute([':q' => $search]);
$total = $countStmt->fetchColumn();

// Выборка результатов
$stmt = $pdo->prepare("SELECT id, title, content FROM articles WHERE title LIKE :q LIMIT :limit OFFSET :offset");
$stmt->bindValue(':q', $search, PDO::PARAM_STR);
$stmt->bindValue(':limit', $perPage, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$results = $stmt->fetchAll();

// Вывод результатов
foreach ($results as $row) {
    echo '

' . htmlspecialchars($row['title']) . '

'; echo '

' . mb_substr(strip_tags($row['content']), 0, 200) . '...

'; } // Постраничная навигация $totalPages = ceil($total / $perPage); for ($i = 1; $i <= $totalPages; $i++) { echo '' . $i . ' '; }

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

Типичные ошибки:

  • Отсутствие экранирования спецсимволов LIKE (%, _). Рекомендуется использовать addcslashes перед подстановкой.
  • Высокая нагрузка при больших объёмах данных - необходимо компенсировать индексами.
  • Использование mysqli без подготовленных запросов - риск SQL-инъекций.

Как улучшить качество поиска с учетом релевантности?

Полнотекстовый поиск MySQL FULLTEXT позволяет ранжировать результаты, учитывать частоту слов и исключать стоп-слова. Для использования требуется предварительно создать полнотекстовый индекс.

// Создание индекса
// ALTER TABLE articles ADD FULLTEXT INDEX ft_title_content (title, content);

$searchTerm = $_GET['q'];
$stmt = $pdo->prepare("SELECT id, title, MATCH(title, content) AGAINST(:q IN BOOLEAN MODE) AS relevance FROM articles WHERE MATCH(title, content) AGAINST(:q IN BOOLEAN MODE) ORDER BY relevance DESC LIMIT 10");
$stmt->execute([':q' => $searchTerm]);
$results = $stmt->fetchAll();

foreach ($results as $row) {
    echo '

' . htmlspecialchars($row['title']) . ' (релевантность: ' . $row['relevance'] . ')

'; }

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

Возможные проблемы:

  • Минимальная длина слова для индексации (по умолчанию 4) - короткие запросы могут не находиться. Изменяется через параметр ft_min_word_len.
  • Необходимость пересоздания индекса при изменении настроек.
  • В режиме BOOLEAN MODE специальные символы (+, -, *) требуют экранирования.

Как выполнить поиск по содержимому файлов на сервере?

Поиск по файлам реализуется с помощью функций glob и preg_match. Сначала получаем список файлов, затем проверяем содержимое.

$searchPattern = '/' . preg_quote($_GET['q'], '/') . '/i';
$files = glob('/path/to/files/*.txt');
$results = [];

foreach ($files as $file) {
    $content = file_get_contents($file);
    if (preg_match($searchPattern, $content)) {
        $results[] = $file;
    }
}

echo '

Найдено файлов: ' . count($results) . '

'; foreach ($results as $file) { echo '

' . basename($file) . '

'; }

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

Типичные ошибки:

  • Чтение больших файлов в память - для снятия ограничений используется fgets или итераторы.
  • Необработанные ошибки доступа к файлам (is_readable) - пропускать такие файлы.
  • Регулярные выражения без preg_quote приводят к ошибкам при специальных символах.
Как фильтровать массивы данных с помощью регулярных выражений?

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

$data = ['apple', 'banana', 'apricot', 'orange'];
$pattern = '/^' . preg_quote($_GET['q'], '/') . '/i';
$filtered = preg_grep($pattern, $data);
print_r($filtered);

Особенности:

  • Шаблон применяется к каждому элементу; учитываются только строки.
  • При пустом запросе возвращается весь массив - нужно проверять входные данные.
- Catalogue php search (поиск по каталогу в php)
- Search php keywords (поиск по ключевым словам в php)
- Search php user (поиск пользователя в php)

Расширенные примеры реализации поиска с просмотром на PHP.

Пример 1: Класс поиска с PDO и пагинацией

Пример
class SearchEngine {
    private $pdo;
    
    public function __construct($dsn, $user, $pass) {
        $this->pdo = new PDO($dsn, $user, $pass);
        $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }
    
    public function search($query, $page = 1, $perPage = 10) {
        $query = '%' . $query . '%';
        $offset = ($page - 1) * $perPage;
        
        $count = $this->pdo->prepare("SELECT COUNT(*) FROM products WHERE name LIKE :q");
        $count->execute([':q' => $query]);
        $total = $count->fetchColumn();
        
        $stmt = $this->pdo->prepare("SELECT id, name, price FROM products WHERE name LIKE :q LIMIT :limit OFFSET :offset");
        $stmt->bindValue(':q', $query, PDO::PARAM_STR);
        $stmt->bindValue(':limit', $perPage, PDO::PARAM_INT);
        $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
        $stmt->execute();
        
        return [
            'results' => $stmt->fetchAll(PDO::FETCH_ASSOC),
            'total' => $total,
            'totalPages' => ceil($total / $perPage)
        ];
    }
}

$engine = new SearchEngine('mysql:host=localhost;dbname=shop', 'root', '');
$searchResults = $engine->search($_GET['q'], $_GET['page'] ?? 1);
foreach ($searchResults['results'] as $product) {
    echo '

' . htmlspecialchars($product['name']) . ' - $' . $product['price'] . '

'; }
Пример вывода (при поиске "phone"):

Smartphone X - $699

Phone case - $15

...

Пример 2: Полнотекстовый поиск с подсветкой совпадений

Пример
$query = 'php framework';
$stmt = $pdo->prepare("SELECT id, title, content, MATCH(title, content) AGAINST(:q IN BOOLEAN MODE) AS relevance FROM articles WHERE MATCH(title, content) AGAINST(:q IN BOOLEAN MODE) ORDER BY relevance DESC LIMIT 5");
$stmt->execute([':q' => $query]);

while ($row = $stmt->fetch()) {
    $highlightedTitle = preg_replace('/(' . preg_quote($query, '/') . ')/i', '$1', $row['title']);
    echo '

' . $highlightedTitle . '

'; echo '

' . mb_substr($row['content'], 0, 300) . '...

'; }
Заголовок статьи "PHP Framework Best Practices" станет:

PHP Framework Best Practices

Пример 3: Поиск по файлам с рекурсией и кешированием

Пример
function searchFiles($dir, $pattern, $exclude = ['.', '..']) {
    $results = [];
    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
    foreach ($files as $file) {
        if ($file->isFile() && pathinfo($file, PATHINFO_EXTENSION) === 'log') {
            $content = file_get_contents($file->getPathname());
            if (preg_match('/' . $pattern . '/i', $content)) {
                $results[] = $file->getPathname();
            }
        }
    }
    return $results;
}

$pattern = 'error';
$found = searchFiles('/var/log', $pattern);
echo '

Найдено ' . count($found) . ' файлов с ошибками:

'; foreach ($found as $f) { echo '

' . $f . '

'; }
Пример вывода:
/var/log/apache2/error.log
/var/log/syslog

Пример 4: AJAX-поиск на PHP (без перезагрузки)

Пример
// search.php
$q = $_POST['q'] ?? '';
$results = [];
if (strlen($q) >= 2) {
    $pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
    $stmt = $pdo->prepare("SELECT name FROM items WHERE name LIKE :q LIMIT 10");
    $stmt->execute([':q' => '%' . $q . '%']);
    $results = $stmt->fetchAll(PDO::FETCH_COLUMN);
}
echo json_encode($results);

// html
При вводе "ph" в поле поиска в ответ приходит JSON: ["php", "photo", "pharmacy"]

Просмотр поиска PHP - comments

En
Search php browse (php)