В этой статье вы узнаете, как создать поиск по содержимому базы данных для вашего сайта. Данный алгоритм поддерживает поиск по нескольким ключевым словам. Алгоритмом будут выбраны строки таблицы базы данных, в которых присутствуют все введенные ключевые слова.
Имеется таблица «news», которая содержит следующие поля: id, title и content:
Требуется осуществить поиск по полю content в нашей базе данных, которая состоит из следующих столбцов, пример смотрите на картинке выше. Приступим к реализации. Для начала создадим страницу для тестирования работы. Она будет содержать форму с полем ввода ключевых слов и кнопку «найти»:
Листинг html кода:
<?session_start();?>
<html>
<head>
<title>Поиск в базе данных</title>
</head>
<body>
<form action="search.php" method="post">
<input type="text" name="string">
<input type="submit" name="submit" value="Найти в БД">
</form>
<? print_r($_SESSION['id']);
unset($_SESSION['id']);
?>
</body>
</html>
В атрибутах формы прописываем путь к обработчику, содержащему алгоритм, и метод передачи post.
Для передачи массива отобранных элементов мы используем сессию.
<? session_start(); ?>
Для этого мы запускаем ее в самом начале страницы.
Для вывода будем использовать функцию print_r().
<? print_r($_SESSION['id']); ?>
Для того чтобы после перезагрузки страницы результат не отобразился второй раз, с помощью unset мы убиваем сессию.
<? unset($_SESSION['id']); ?>
Создадим обработчик search.php. Для начала запускаем сессию и подключаемся к базе данных:
<?
session_start();
$params = array (
'host' => 'localhost',
'dbname' => 'ggwp',
'user' => 'ggwp',
'password' => '123456',
);
$dsn = "mysql:host={$params['host']};dbname={$params['dbname']}";
$db = new PDO($dsn, $params['user'], $params['password']);
$db->exec("set names utf8");
?>
Подробнее о подключении к базе данных через PDO смотрите в этой статье.
Работа алгоритма представлена на схеме:
Разберем выборку по первому слову, в качестве примера будем использовать поисковый запрос «как сделать сайт»:
<?
$str = $_POST['string'];
$mass = explode(' ', $str);
$count = count($mass);
$sql = "SELECT id, content FROM news WHERE content LIKE '%".$mass[0]."%'";
$result = $db->query($sql);
$result->setFetchMode(PDO::FETCH_ASSOC);
$id_mass = array();
$i=1;
while ($row=$result->fetch()) {
$id_mass[$i] = $row['id'];
$i++;
}
$id_count = count($id_mass);
?>
Сначала в переменую $str получаем строку из формы методом POST. Разбиваем эту строку на слова через пробел с помощью функции expode и подсчитываем количество слов. Осуществляем запрос, в котором проверяем наличие первого слова в столбце content. Создаем пустой массив и записываем в него значения, полученные в результате выборки по запросу. Записываем в $id_count количество полученных элементов.
Далее рассматриваем остальную часть схемы, на которой отображается по второму и последующим ключевым словам:
<?
for ($i=1; $i<=$count-1; $i++) {
for ($j=1; $j<=$id_count; $j++) {
$sql = "SELECT id, content FROM news WHERE id=".$id_mass[$j]." AND content LIKE '%".$mass[$i]."%'";
$result = $db->query($sql);
$result->setFetchMode(PDO::FETCH_ASSOC);
$result->execute();
$id_mass2 = array();
$row=$result->fetch();
$temp = $row['id'];
if($temp!=$id_mass[$j]) {
$id_mass[$j] = -1;
}
}
}
?>
Эта часть алгоритма работает по принципу «отсеивания». Допустим в базе данных имеется десять статей. После выборки по первому слову мы получаем id статей в которых есть слово «как», таких статей оказалось шесть. Далее мы производим поиск второго слова среди этих шести статей, тем самым сузив круг поиска. В результате этой итерации остается четыре статьи, которые включают в себя оба слова «как» и «сделать». На последней итерации среди оставшихся четырех статей мы ищем слово «сайт». После этого прохода получаем id одной единственной статьи, которая включает в себя все ключевые слова.
Количество итераций равно количеству слов в поисковом запросе. Конечное количество полученных id может быть любым, в зависимости от запроса и содержимого таблицы базы данных.
Если в результате выполнения запроса в цикле мы получаем id (переменная temp), равное одному из id предыдущей выборки (id_mass[]), то этот id мы оставляем неизменным. В противном случаем мы присваиваем элементу id_mass[ j ] значение -1, тем самым исключив его из обработки.
После окончания работы циклов мы получаем массив из id, в которых найдены ключевые слова и -1. Чтобы передать пользователю только требуемые id, мы используем цикл, в котором идет проверка, в результате которой отбрасываются все элементы равные -1. Остальные же элементы мы передаем в массив сессии:
<?
$l=1;
for($i=1; $i<$id_count+1; $i++) {
if ($id_mass[$i] == -1) continue;
else {
$_SESSION['id'][$l] = $id_mass[$i];
$l++;
}
}
header('Location: /index.php');
?>
Функция header служит для перенаправления клиента на страницу поиска.
В результате выполненных действий мы получили функцию поиска по таблице базы данных. После небольших модификаций этот алгоритм может быть использован для получения и поиска любых полей в любой базе данных.
Смотрите также дополнительные статьи про MVC
Комментарии ( 1 )
Я думаю, это можно сделать намного проще: $str = $_POST['string']; $mass = explode(' ', $str); $count_mass = count($mass); for ($i=0; $i <$count_mass ; $i++) { if ($i==0) { $part1="`content` LIKE '%".$mass[0]."%'"; } else{ $part2 ="AND `content` LIKE '%".$mass[$i]."%'"; $part1 = $part1.$part2; } } $query = "SELECT * FROM `news` WHERE".$part1."ORDER BY `id` DESC "; Так мы сразу получим что надо.
18.12.2019