Поиск по сайту AJAX + PHP + MySQL (PHP + MySQL)
Добрый день дорогие друзья, здравствуйте.
Никак не дает мне покоя вопрос организации пользовательского поиска по сайту.
И в этой статье я снова хочу обратиться к нему и рассказать как реализовать поиск используя связку AJAX + PHP + MySQL.
То есть на этот раз я не буду пользоваться услугами сторонних сервисов, а покажу как это можно реализовать самостоятельно, используя лишь только то, чем мы располагаем. А именно: cервер PHP и сервер MySQL с развернутой на нем базой данных в которой хранится иформация о сайте.
А связать все воедино - передачу поискового запроса серверу и выдачу информации по нему в браузер после обработки, поможет технология AJAX.
Реализовывать поиск, по моему замыслу, мы будем с помощью AJAX (клиентская часть) и PHP + MySQL(серверная часть)
Цели определены, давайте теперь разработаем алгоритм наших действий
Сформулируем сначала задачу:
Из поисковой формы с помощью технологии AJAX, основы которой продемонстрированы в статьях "Пример AJAX приложения - Телефонная книга (сервер)" и "Пример Ajax приложения - Телефонная книга (клиент)", строка запроса передается на сервер, где в PHP скрипте происходит его обработка и формируется запрос к базе данных MySQL.
Скрипт PHP получает от сервера MySQL ответ с результатами поиска в базе данных, генерирует HTML с поисковой выдачей и AJAX - ом передает его клиенту(браузеру), после чего он отображается на экране.
В сегодняшней статье я рассмотрю связку PHP + MySQL и покажу как как организовать простой вывод найденной информации в браузер. А уже в статье "Поиск по сайту AJAX + PHP + MySQL (AJAX)" я рассмотрю как "прикрутить" ко всему этому AJAX оптимизировав тем самым вывод поисковой информации пользователю.И так, приступим
Для наглядности я решил объединить весь код в один файл. Но вы должны учесть, что если интеграция кода HTML и PHP дело в общем обычное, то объединение в один файл конфигурационных настроек подключения к базе данных, вспомогательных функций PHP и непосредственно самого исполняемого скрипта PHP в один файл дело недопустимое, и что конечно правильнее разносить их по отдельным файлам. Так сказать мухи отдельно, котлеты отдельно.
Для начала вот вам код, который у меня получился:
<form name="search" method="post" action="search.php"> <input type="search" name="query" placeholder="Поиск" /> <button type="submit">Поиск</button> </form> <?php header ("Content-type:text/html; charset=utf-8"); /////////////// Определяем используемые функции ////////////////// /* Открываем соединение с базой данных*/ function connectDB (){ // Определяем константы для соединения с базой данных define('DB_HOST', 'localhost'); define('DB_USER', 'root'); define('DB_PASS', 'password'); define('DB_NAME', 'db_name'); //Пытаемся соединится с базой данных $dbconn = mysql_connect(DB_HOST, DB_USER, DB_PASS) or die("Ошибка соединения с базой данных! " . mysql_error()); //и выбрать таблицу mysql_select_db(DB_NAME); // Устанавливаем кодировку mysql_query('SET NAMES utf8'); //Возвращаем дескриптор соединения return $dbconn; } /*Закрываем соединение с базой данных*/ function closeDB($dbconn){ mysql_close($dbconn); } /*Обработка поискового запроса*/ function search ($query) { $text = ''; // Проводим фильтрацию данных $query = trim($query); // Обрезаем пробелы и спецсиволы $query = strip_tags($query); // Удаляем HTML и PHP теги $query = mysql_real_escape_string($query); // Экранируем специальные символы //Поисковый запрос не пустой? if (!empty($query)){ if (strlen($query) < 4) { $text = '<p>короткий поисковый запрос.</p>'; }elseif (strlen($query) > 128) { $text = '<p>длинный поисковый запрос.</p>'; } else { //Формируем строку поискового запроса $sql = "SELECT `id`, `title`, `description`, `link` FROM `name_table` WHERE `description` LIKE '%$query%' OR `title` LIKE '%$query%'"; // и выполняем его $result = mysql_query($sql); //Определим колличество найденных совпадений $num = mysql_num_rows($result); //Если число совпадений (строк результата запроса) больше 0 if ( $num > 0) { //Получаем ассоциативный массив $row = mysql_fetch_assoc($result); //и начинаем формировать строку поисковой выдачи $text .= '<p>По вашему запросу <strong>'.$query.'</strong>'; $text .= ' найдено '.$num.' совпадений</p>' ; do { //Продолжаем формировать строку поисковой выдачи $text .= '<p><a href="http://'.$row['articleId'].'">'; $text .= $row['title'].'</a></p>'; $text .= '<p>'.$row['tinyDescription'].'</p>'; // Делаем это пока у нас есть результаты } while ($row = mysql_fetch_assoc($result)); } else { // Найти совпадение не удалось $text = '<p>По вашему запросу ничего не найдено.</p>'; } } }else { $text = '<p>Задан пустой поисковый запрос.</p>'; } //Возвращаем сформированную строку поисковой выдачи return $text; } ///////////// Сам скрипт обработчик /////////////// if (isset ($_POST['query'])){ // Открываем соединение с базой данных $connect = connectDB(); $search_result = search ($_POST['query']); echo $search_result; // Закрываем соединение с базой данных closeDB ($connect); } ?>
Ну вот, а теперь, когда вы бегло просмотрели код, давайте разберем как он работает.
Первым делом создадим форму поиска , которая отправляет поисковый запрос серверу:
<form name="search" method="post" action="search.php"> <input type="search" name="query" placeholder="Поиск" /> <button type="submit">Поиск</button> </form>
Думаю, что по по HTML форме у вас не должно возникнуть вопросов, но если это все таки случится, то ответы на них можно найти в статьях: "О HTML формах и не только", "HTML, формы и CSS (часть1 - HTML)" и "HTML, формы и CSS (часть2 - CSS)"
А вот на скрипте отвечающем за соединение с базой данных MYSQL и выполнением запроса к базе хочу остановится немного поподробнее
Сначала идет блок кода в котором инициализируются параметры для подключения к базе данных и создается само подключение - функция connectDB(), а также функция closeDB() - которая закрывает соединение с базой данных. Естественно, что данные названий таблиц, выбираемых из таблиц параметров, пароля для подключения к базе данных и имя самой базы данных нужно задать собственные.
<?php /* Открываем соединение с базой данных*/ function connectDB (){ // Определяем константы для соединения с базой данных define('DB_HOST', 'localhost'); define('DB_USER', 'root'); define('DB_PASS', 'password'); define('DB_NAME', 'db_name'); //Пытаемся соединится с базой данных $dbconn = mysql_connect(DB_HOST, DB_USER, DB_PASS) or die("Ошибка соединения с базой данных! " . mysql_error()); //и выбрать таблицу mysql_select_db(DB_NAME); // Устанавливаем кодировку mysql_query('SET NAMES utf8'); //Возвращаем дескриптор соединения return $dbconn; } /*Закрываем соединение с базой данных*/ function closeDB($dbconn){ mysql_close($dbconn); }
А дальше мы подошли к основной функции search() в которой происходит вся основная работа, и в которую передается параметр для обработки - строка запроса $query.
/*Обработка поискового запроса*/ function search ($query) { $text = '';
Сначала фильтруем строку запроса обрезая пробелы и управляющие символы trim(), экранируя специальные символы mysql_real_escape_string(), чтобы запрос стал безопасным для базы данных. Настоятельно рекомендую проводить такую обработку , так как любая форма на Вашем сайте - это потенциальная уязвимость, образно говоря "черный вход" для злоумышленников. Ведь вы же не собираетесь оставить его открытым?
// Проводим фильтрацию данных $query = trim($query); // Обрезаем пробелы и спецсиволы $query = strip_tags($query); // Удаляем HTML и PHP теги $query = mysql_real_escape_string($query); // Экранируем специальные символы
Далее переходим непосредственно к поисковому запросу Сначала проверим не пустой !empty() ли пришел поисковый запрос?
Если запрос пустой, то возвращаем соответствующее сообщение пользователю. Если проверка пройдена, проверяем его на размер.Нас не интересуют запросы короче 4 или длиннее 128 символов. Запрос не удовлетворяет нашим требованиям - снова выводим соответствующие сообщения для пользователя. Ну а если все хорошо, выполняем запрос к базе данных.
//Поисковый запрос не пустой? if (!empty($query)){ if (strlen($query) < 4) { $text = '<p>короткий поисковый запрос.</p>'; }elseif (strlen($query) > 128) { $text = '<p>длинный поисковый запрос.</p>'; } else {
А вот с этого места поподробнее...
Сначала в строковой переменной $sql формируем строку запроса. C помощью оператора SELECT, который делает выборку идентификатора страницы (id), ее заголовка (title), описания (description) и ссылки на страницу (link), выбираем из таблицы (FROM table_name) значения полей где (WHERE) в любом месте заголовка или описания содержится наш поисковый запрос ( `description` LIKE '%$query%' OR `title` LIKE '%$query%').
//Формируем строку поискового запроса $sql = "SELECT `id`, `title`, `description`, `link` FROM `name_table` WHERE `description` LIKE '%$query%' OR `title` LIKE '%$query%'"; // и выполняем его $result = mysql_query($sql); //Определим колличество найденных совпадений $num = mysql_num_rows($result); //Если число совпадений (строк результата запроса) больше 0 if ( $num > 0) { //Получаем ассоциативный массив $row = mysql_fetch_assoc($result); //и начинаем формировать строку поисковой выдачи $text .= '<p>По вашему запросу <strong>'.$query.'</strong>'; $text .= ' найдено '.$num.' совпадений</p>';
Если найти ничего не удалось - выводим об этом сообщение пользователю. Если запрос возвратил хотя бы одну запись, формируем в цикле (DO WHILE ) особенностью которого является, что он выполняется по крайней мере один раз, строку ответа сервера клиенту с результатами поисковой выдачи. Естественно, что если запрос к базе вернул не одну, а несколько записей, то все они в цикле методом конкатенации "пристыкуются" к нашему результату.
do { //Продолжаем формировать строку поисковой выдачи $text .= '<p><a href="http://'.$row['articleId'].'">'; $text .= $row['title'].'</a></p>'; $text .= '<p>'.$row['tinyDescription'].'</p>'; // Делаем это пока у нас есть результаты } while ($row = mysql_fetch_assoc($result)); } else { // Найти совпадение не удалось $text = '<p>По вашему запросу ничего не найдено.</p>'; } } }else { $text = '<p>Задан пустой поисковый запрос.</p>'; }
Ну и в конце работы функции возвращаем в главный скрипт результат.
//Возвращаем сформированную строку поисковой выдачи return $text; }
Ну а далее идет блок кода, который по идее должен быть отдельным файлом search.php, и в котором подключаются все наши функции
///////////// Сам скрипт обработчик /////////////// if (isset ($_POST['query'])){ // Открываем соединение с базой данных $connect = connectDB(); $search_result = search ($_POST['query']); echo $search_result; // Закрываем соединение с базой данных closeDB ($connect); } ?>
Как вам скриптец? Не поразил размерами? А ведь именно от него все и зависит. Разберем его работу.
Сначала он проверяет существует ли isset() и не пустой ли !empty() пришедший нам методом POST['query'] запрос от клиента (браузера). Если все OK, открываем соединение с базой данных Mysql и вызываем нашу функцию search(), в которую передаем поисковый запрос.
Следующая строка выводит ответ от сервера каким бы он не был.
Ну и конечно, не забываем закрыть соединение с базой данных, передавая ему дескриптор соединения - $connect, после окончания работы.
Простейший поиск по сайту с использованием PHP и MySQL готов. Конечно вы можете модернизировать его по своему усмотрению.
А в статье "Поиск по сайту AJAX + PHP + MySQL (AJAX)" я покажу как расширить скрипт php и подключить подключить к ним AJAX А на сегодня у меня все. А если у вас возникли вопросы - пожалуйста задавайте. До свидания и надеюсь на скорую встречу.
Автор: Сергей Зарубин
Дата: 2012-04-25
Колличество просмотров: 26090
|
Нравится |
Комментарии к заметке:
Комментарий добавил(а): eihwas
Дата: 2013-03-13
Спасибо огромное! Более подробной инструкции в сети нет. Всё работает, всё просто, лаконично и, что главное, благодаря вашим пояснениям, всё понятно.
Комментарий добавил(а): Михаил
Дата: 2013-04-20
Скрипт хороший. Спасибо автору. А нельзя ли сделать подсветку в тексте искомого слова?
Комментарий добавил(а): Сергей Зарубин
Дата: 2013-04-21
Обратитесь к посту "Поиск по сайту jQuery + AJAX + PHP + MySQL", в котором я показал как "подсветить" поисковый запрос в поисковой выдаче и оформить результаты выдачи в виде ссылок.
Комментарий добавил(а): Михаил
Дата: 2013-04-21
спасибо, Сергей, пойду гляну. Динамическая аяксовая выдача просто поразила)) поковыряюсь...
Комментарий добавил(а): Ксения
Дата: 2013-04-29
Одно НО! Когда нажимаешь на кнопку поиск, не выводит: "Пустой поисковый запрос!" Просто пустота.
Комментарий добавил(а): Сергей Зарубин
Дата: 2013-04-30
Вы совершенно правы. Всему виной строка:
///////////// Сам скрипт обработчик ///////////////
if (isset ($_POST['query']) && !empty($_POST['query']))
Поправил.
Комментарий добавил(а): Ксения
Дата: 2013-04-30
Нет, надо так
if ((isset ($_POST['query']) && empty($_POST['query'])) or (isset ($_POST['query']) && !empty($_POST['query'])))
Комментарий добавил(а): Сергей Зарубин
Дата: 2013-05-01
А вот здесь позвольте с вами не согласится
в строке
if ((isset ($_POST['query']) && empty($_POST['query'])) or (isset ($_POST['query']) && !empty($_POST['query'])))
вы предлагаете проверять два взаимоисключающих случая empty() и !empty() и разрешаете их оба. Зачем?
Комментарий добавил(а): Ксения
Дата: 2013-05-01
Не "и", а "или".
Со стракой if (isset ($_POST['query']) && !empty($_POST['query'])) вывод только не пустого запроса.
Комментарий добавил(а): Сергей Зарубин
Дата: 2013-05-01
Ксения, наверное вы не обратили внимания, но после вашего первого справедливого замечания я заменил в коде строчку
///////////// Сам скрипт обработчик ///////////////
if (isset ($_POST['query'] ) && !empty($_POST['query']))
///////////// Сам скрипт обработчик ///////////////
if (isset ($_POST['query']))
if (!empty($query)){
Комментарий добавил(а): Алексей
Дата: 2013-11-14
Здравствуйте.
Все супер, спасибо большое. Я хоть и не силет в рнр да и вообще не програмист, так, самоучка. Но мне кажется что тут
$sql = "SELECT `id`, `title`, `description`, `link`
FROM `name_table` WHERE `description` LIKE '%$query%'
OR `title` LIKE '%$query%'";
нехватает 'articleId'
по крайней мере у меня без нее не тянет под ссылку адрес.
Комментарий добавил(а): Евгений
Дата: 2014-03-14
Может, я чего-то не понял? Пользователь ввел в поиск фразу, мы убрали спецсимволы и слепили ее в одно слово без пробелов? Мы ничего не найдем, тем более лайком.
И еще.. для вывода результатов вместо if'a и цикла с постусловием не проще ли использовать сразу цикл с предусловием? Запись будет короче, на мой взгляд
Комментарий добавил(а): Сергей
Дата: 2014-07-14
как сделать выборку по всем таблицам в БД для поиска?
Комментарий добавил(а): Руфина
Дата: 2014-07-18
немного не допонемаю. Слово,которое вводим в поле поиска, должно содержаться в нашей таблице в поле title или в поле description, я правильно понимаю?если оно в таблице есть, то возвращается ссылка на страницу, где есть это слово?
Комментарий добавил(а): Евгения
Дата: 2014-08-01
как сделать выборку по всем таблицам в БД для поиска?
Комментарий добавил(а): Евгений
Дата: 2014-11-24
Здравствуйте, у меня такая ситуация абитуриенты сдали тесты и надо по ФИО сделать выборку с выводом страки с отметками по тестам и ошибками. Как это сделать?
Комментарий добавил(а): Евгений
Дата: 2015-04-23
"И так, приступим" - "итак" пишется слитно в вашем случае..
Комментарий добавил(а): Руслан
Дата: 2015-09-22
Можно описание БД, описание как вводить данные в БД, а то получается только половина описания, а те кто вообще не бум-бум в БД - будут сидеть и думать что ничего не работает.
Комментарий добавил(а): Сергей Зарубин
Дата: 2015-12-09
Существует множество вариантов для выборки данных из нескольких таблиц.
Вот для примера:
SELECT table_1.*, table_2.* FROM table_1, table_1 ON t1.id = t2.id
SELECT * FROM table_1, table_2 WHERE ....
SELECT table_1.*, table_2.* FROM table_1 LEFT JOIN table_2 ON t1.id = t2.id
SELECT table_1.*, table_2.* FROM table_1 LEFT JOIN table_2 USING (id)
Комментарий добавил(а): bonfynk
Дата: 2016-02-08
Спасибо большое. Легко изменил под свои нужды. Все очень понятно и доходчиво. Очень интересно использование в скрипте do while честно не додумался что можно сделать именно так чтобы выводилось несколько записей а не одна.
Комментарий добавил(а): Алекс
Дата: 2018-05-14
Статья хорошая, но незаконченная. Негоже давать урок по работе скрипта в отрыве от создания и работы БД.
Добавить новый комментарий