maxidebox@list.ru | +7 (929) 701 21 71
Подходящий поиск на php

Подходящий поиск на php

Как можно сделать более хороший подходящий поиск по сайту с помощью php в связке с mysql.

Часто встречаются сайты, на которых поиск идет по средствам деления фразы на слова и выводились результаты не те, которые нужны пользователю. Предлагаем рассмотреть наш скрипт, который будет выдавать результаты в более подходящем порядке.

Структура базы

В БД создаем несколько таблиц:

1. Страница контента


CREATE TABLE `content` (
	`page_id` INT NOT NULL AUTO_INCREMENT ,
	`page_name` TEXT NOT NULL ,
	`page_curl` TEXT NOT NULL ,
	`page_text` TEXT NOT NULL ,
	`page_views` INT NOT NULL ,
	PRIMARY KEY ( `page_id` ) ,
	UNIQUE (
		`page_id`
	)
) ENGINE = MYISAM ;

2. Страница запросов


CREATE TABLE `search_words` (
	`word_id` INT NOT NULL AUTO_INCREMENT ,
	`word_words` TEXT NOT NULL ,
	`word_count` INT NOT NULL ,
	PRIMARY KEY ( `word_id` ) ,
	UNIQUE (
		`word_id`
	)
) ENGINE = MYISAM ;

После создания таблиц в БД пишем php код

1. Принять и почистить данные

Все данные передаем методом POST для того, чтобы никто не менял адресную строку. Фраза, которую ищет пользователь будет храниться в переменно: $_POST[«words»].

Для начала нам нужно поставить защиту от нежелательных атак.


function clean_post_data($data){
	$data = strip_tags($data);
	$data = strtolower($data);
	$data = preg_replace('~[^a-z0-9 \x80-\xFF]~i', "",$data); 
	return $data;
}

Данная функция очистит все ненужное из текста.

Вторым шагом мы создадим функцию которая позволит создать массив с нужными для поиска словами:


function clean_array_to_search($words = array(), $max = 0, $min_length){
	$result = array();
	$i = 0;
	foreach($words as $key => $value){
		if(strlen(trim($value)) >= $min_length){
			$i++;
			if($i <= $max){
				$result[] = trim($value);
			}
		}
	}
	return $result;
}

Третьим шагом мы составим функцию, которая будет выбирать из базы данных страницы, которые подходят под поисковую фразу.


function get_results($words){
	$sql = "SELECT * FROM (`content`) WHERE ";
	$i = 0;
	foreach($words as $key => $value){
		$i++;
		$sql = $sql." `page_name` LIKE '%".$value."%' OR `page_text` LIKE '%".$value."%'".($i==count($words)?"":" OR");
	}
	$sql .= " ORDER BY `page_views` DESC";
	$result = mysql_query($sql);
	while($row = @mysql_fetch_object($result)){
		$return = $row;
	}
	return $return;
}

После того, как мы получили массив с данными нам нужно отсортировать его с помощью функции.


function get_matches($content, $word = array()){
	$matches = array();
	foreach($content as $p){
		$res[$p->page_id] = $p;
		foreach($word as $w){
			if(trim($w) != ""){
				$w = trim($w);
				$matches[$p->page_id] = $matches[$p->page_id] + count(explode($w, $p->page_name));
				$matches[$p->page_id] = $matches[$p->page_id] + count(explode($w, $p->page_text));
			}
		}
	}
	arsort($matches);
	$i = 0;
	foreach($matches as $k => $v){
		$result[$i] = $res[$k];
		$result[$i]->matches = $v;
		$i++;
	}
	return $result;
}

В результате, чтобы сделать поиск нам нужно сделать следующее.


$max = 10; // максимальное количество слов во фразе
$min_length = 3; // минимальная длина искомого слова
$word = explode(" ", clean_post_data($_POST["word"]));
$words = clean_array_to_search($word, $max, $min_length);
$results = get_results($words);
$result = get_matches($results, $words);

Мы получили список того, что пользователь искал, причем в нужном ему порядке. В самом начале была информация, что данные передаются методом POST поэтому нужно выполнить еще пару команд, чтобы можно было видеть результаты поиска:


function insert_into_search_table($words = array()){
	$words = implode(" ", $words);
	$sql = "INSERT INTO `search_words` (`word_id`, `word_words`) VALUES (NULL, '".$words."');";
	mysql_query($sql);
	return intval(mysql_insert_id());
}

В самый верх страницы мы вставим следующую строку, для того, чтобы любой, пройдя по ссылке мог получить те результаты которые получил ранее.


if(isset($_GET["words_id"]) AND $_GET["words_id"] != "" AND $_GET["words_id"] == intval($_GET["words_id"])){
	$row = mysql_query("SELECT * FROM `search_words` WHERE `word_id` = '".intval($_GET["words_id"])."';");
	$row = @mysql_fetch_array($row);
	$_POST["word"] = $row["word_words"];
}

В итоге вы получаете массив с объектами: $result.

Голосов: 349 | Просмотров: 549