Организация поискового просмотра на 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);Особенности:
- Шаблон применяется к каждому элементу; учитываются только строки.
- При пустом запросе возвращается весь массив - нужно проверять входные данные.
Расширенные примеры реализации поиска с просмотром на 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"]