Пишем собственное поисковое ядро. Часть 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">
  <h4><a href='index.php?cat=&mat=&style=1'></a></h4>
  ".substr($value[text],0, 430)."...

"; echo $text; ?>
  <p>Количество совпадений: </p>


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

Спасибо за внимание.

  • FalleN

  • 1600

  • 1

  • 0
Теги: ядро, поиск

Ссылки на статью:

Похожие статьи: