Пишем собственное поисковое ядро. Часть 2.
Продолжаем разработку нашего поискового ядра. В данном уроке мы напишем еще несколько функций и рассмотрим работу с шаблоном.
Первая часть урока
1. Форма поиска и передаваемые данные
Небольшое отступление сделаем и посмотрим на нашу форму отправки данных:
Code
<form action="search_result.php" method="post">
<p><input id="search_input" name="search_word" type="text"><input id="search_button" type="submit"></p>
</form>
Как видите тут ничего необычного нет. Мы передаем значение search_word файлу search_resul.php. Т.е. у нас в нашей системе добавился файл куда и будут выводиться результаты поиска и теперь наша структура выглядит вот так:
Т.е. в файле search_result.php мы будем получать значение запроса и обрабатывать его примерно таким образом:
Code
if(isset($_REQUEST["search_word"])) {
$query = trim($_REQUEST["search_word"]); //делаем небольшую чистку, можете добавить еще защиту от различных инъекций и подозрительных переменных, которые могут ввести вам вредные пользователи
$keywords = explodeQuery($query); //тут наша функция с первой части урока
$sql = "SELECT id, title, keywords, text, category FROM materials WHERE public=1"; //ищем только опубликованные материалы
$result = mysql_query($sql);
if (@mysql_num_rows($result)!=0) { //проверяем наличие записей, если нет, то естественно ничего не выведем и прекратим любую работу системы
while($row = mysql_fetch_assoc($result))
{
$materials[$row[id]] = $row; //Формируем массив $materials с найденными материалами
}
echo searchResult($materials,$keywords); //выводим наш результат поиска, функцию мы рассмотрим ниже
}
else {
echo "напишем тут какую-нибудь ошибку для пользователя";
}
}
Как видите ничего сложного тут нет. У нас как видите появилась одна необъявленная функция searchResult(). Ее написанием сейчас мы и займемся.
2. Результат поиска.
Рассмотрим немного схему того, как система будет искать необходимые пользователю материалы:
Составитель схем из меня никудышный, но думаю смысл понятен. Поэтому приступим к написанию функции.
Code
function searchResult($materials, $keywords) {
foreach ($materials as $material) { //Выше мы сформировали массив $materials который мы теперь выводим разбивая на элементы массива $material
$title = htmlspecialchars(strip_tags($material[title])); //Тут мы чистим все значения массива - title, text и keywords от тегов и посторонних символов
$text = htmlspecialchars(strip_tags($material[text])); //как вариант можно еще все слова перевести в нижний регистр
$key = htmlspecialchars(strip_tags($material[keywords]));
$wordWeight =0; //вес слова запроса приравниваем к 0
foreach ($keywords as $word) { //теперь для каждого поискового слова из запроса ищем совпадения в тексте
$reg = "/(".$word.")/"; //маска поиска для регулярной функции
/*
Автоматически наращиваем вес слова для каждого элемента массива.
Так же сюда можно включить например поле description если оно у вас есть.
Оставляем переменную $out, которая выводит значение поиска. Она нам может и не пригодится, но пусть будет, может быть вы найдете ей применение.
*/
$wordWeight = preg_match_all($reg, $title, $out); //как вариант можно еще для слов в заголовке вес увеличивать в два раза
$wordWeight += preg_match_all($reg, $text, $out); //но это вам понадобиться если вы будете выводить материалы в порядке убывания по релевантности
$wordWeight += preg_match_all($reg, $key, $out); //мы же пока этого делать не будем
$material[relevation] += $wordWeight; //увеличиваем вес всего материала на вес поискового слова
//раскрашиваем найденные слова функцией, которую мы писали в первой части урока
$title = colorSearchWord($word, $title, "violet");
$text = colorSearchWord($word, $text, "violet");
$key = colorSearchWord($word, $key, "violet"); //незнаю зачем ключевые слова окрасил, их ведь не обязательно выводить пользователю <img src="http://s57.ucoz.net/sm/1/smile.gif" border="0" align="absmiddle" alt="smile" />
}
//Теперь ищем те материалы, у которых временный атрибут relevation не равен 0
if($material[relevation]!=0) {
//Возвращаем массивы в нормальное состояние с уже обработанными данными
$material[title] = $title;
$material[text] = $text;
$material[keywords] = $key;
echo simpleToTamplate($material, "search_result"); //новая функция, которая вернет нам шаблон с результатами поиска
}
//Иначе просто грохаем весь элемент material за ненадобностью
else {
unset($material);
}
}
}
Вот такая сложная функция, в которой у нас появилась еще одна новая функция и мы ее сейчас рассмотрим отдельно. Что касательно этой функции то смысл ее прост, она просто проверяет вхождение каждого слова в три атрибута материала и увеличивает временно создаваемый атрибут (его нет в базе данных!) для того, чтобы определить, какие материалы нам подходят.
3. Шаблон и функция его вызова.
Ну вот собственно мы подходим к функции визуального формирования результата запроса на основании шаблона search_result.tpl. Для начала рассмотрим функцию, которая при помощи буфера позволит нам динамически сформировать всю структуру HTML.
Code
function simpleToTamplate($value, $tamplate) {
ob_start(); // Включаем буферизацию вывода, чтобы шаблон не вывелся в месте вызова функции
// Подключаем необходимый нам шаблон, который просто ждет наш массив
include('tamplates/'.$tamplate.'.tpl');
return ob_get_clean(); //Возвращаем результат буфера и очищаем его
}
Функция достаточно небольшая, она передает нашему шаблону массив данных и материала, а тот в свою очередь собирает нам вменяемую HTML верстку, которую мы определим в самом шаблоне result_search.tpl.
Code
<div id="search_result_element echo $value[id] ?>">
<h4><a href='index.php?cat==$value[category] ?>&mat==$value[id] ?>&style=1'>=$value[title] ?></a></h4>
$text = "
".substr($value[text],0, 430)."...
"; echo $text; ?><p>Количество совпадений: =$value[relevation];?></p>
Вот собственно и готов поиск. В следующих уроках мы подумаем как улучшить наше ядро, рассмотрим новые приемы работы с массивами и улучшим в целом всю систему. Пример работы поиска можно посмотреть например на сайте www.protege-star.com
Спасибо за внимание.
-
FalleN -
1667 -
1 -
0
Но только нужно ставить наверное на те модули которые обновляться должны не раньше через пару тройку минут
С Уважением, Андрей...