Скрипт поиска по mysql

Rus

Guest
Скрипт поиска по mysql

Вообще я на php программирую еще очень мало! И месяца нет, как этим делом занялся. Короче, написал скрипт поиска для своей базы и теперь очень хочу чтобы вы его оценили (как всегда очень сильно поругали)! Буду рад каждому замечанию ;)

PHP:
<?php 
require_once ("./class.php");

//все пишу с register_globals  Off
if (!isset($HTTP_GET_VARS["p"])) $p="";
else $p = $HTTP_GET_VARS["p"];


switch($p)
{
case "":
	search_form();
break;

case "search":
	xsearch($HTTP_GET_VARS['s'], $HTTP_GET_VARS['logic']);
break;
}

//форма поиска
function search_form()
{
echo "<form action=search.php method=get>
<input type=hidden name=p value=search>
Что ищем: 
<input type=text name=s>
<select name='logic'>
<option value='OR'>искать любое из слов
<option value='AND'>искать все слова
</select>
<input type=submit value=' search '><br><br>
</form>";
}

//функция осуществляет поиск
function xsearch($s, $logic)
{
//проводим все возможные проверки
$s = substr($s, 0, 64);
$s = preg_replace("/[^\w\x7F-\xFF\s]/", " ", $s);
$good = trim(preg_replace("/\s(\S{1,2})\s/", " ", ereg_replace(" +", "  "," $s")));
$good = ereg_replace(" +", " ", $good);
$good = str_replace("ё", "е", $good);
$word = explode(" ", $good);

//это а тот случай если $logic не установлен
if (($logic!="AND") && ($logic!="OR"))
	$logic = "OR";

	
$query = "SELECT s_id, name FROM arts WHERE atext LIKE '%";
$i = 0;
$c = count($word);
while ($i < $c) 
   {
  if (strlen($word[$i])>2)
  	if ($i == ($c-1))
  		$query .= addslashes($word[$i])."%'"; //если последнее слово
	else  
		$query .= addslashes($word[$i])."%' $logic atext LIKE '%"; //если будут еще слова
  $i++;	
  };
  
$result = query_sql($query); //query_sql() -  mysql_query() но уже с проверками
$r = mysql_numrows($result); //количество найденых строк

echo "<b>Искали:</b> <i>$s</i><br>";
echo "<b>Количество найденных статей: $r</b><br><br>";

while($row=mysql_fetch_array($result))  
{
 echo "<a href=article.php?id=".$row['s_id'].">".$row['name']."</a><br>";
}
    	    
}

?>
 

SunDrop

Помощник поисков. робота
1) По поводу LIKE - покопайся в мануале на тему FULTEXT index.
2) Вместо блока
PHP:
//все пишу с register_globals  Off
if (!isset($HTTP_GET_VARS["p"])) $p="";
else $p = $HTTP_GET_VARS["p"];


switch($p)
{
case "":
    search_form();
break;

case "search":
    xsearch($HTTP_GET_VARS['s'], $HTTP_GET_VARS['logic']);
break;
}
Я б писал:
PHP:
switch($_GET['p'])
{
    case "search":
        xsearch($_GET['s'], $_GET['logic']);
        break;

    default:
        search_form();
        break;
}
Ибо зачем тебе блок с присвоением p, если потом это не используется?
 

Фанат

oncle terrible
Команда форума
тут и case не нужен.
да и вообще очень много лишнего.

-~{}~ 22.03.05 10:03:

Rus
во-первых, все эти проверки
$good = trim(preg_replace("/\s(\S{1,2})\s/", " ", ereg_replace(" +", " "," $s")));
$good = ereg_replace(" +", " ", $good);
$good = str_replace("ё", "е", $good);
$word = explode(" ", $good);
совершенно безумные и бессмысленные.
какая-то мешанина из регов, прегов, ерегов...
смысла во всех этих заменях - ноль.
всё, что тебе нужно - это обрезать строку, если ты уж так уж боишься, что подсунут слишком длинную, и разбить её один прег сплитом на слова
PHP:
  $s = (substr(trim($s), 0, 64); 
$words = preg_split("!\s!", $s);
и всё.

Дальше. длинный цикл с повторами тебе тоже не нужен.
в цикле надо только обработать слова из массива. а строку собирать надо с помощью implode.

никакие кейсы с функциями тут тоже не нужны
структура у приложения - примитивнейшая. ОДИН условный переход. нафига тут кейсы? зачем функции, которые используются всего 1 раз?

PHP:
if (isset($_GET['s'])) {
//выводим результаты поиска
} else {
?> 
<form action=search.php method=get> 
</form>
<? } ?>
и всё.
чё там городить-то?
 

Rus

Guest
То, что я и хотел. Буду исправлять. Спасибо :)
 

Фанат

oncle terrible
Команда форума
как исправишь - приноси. дальше будем шерстить.
 

Rus

Guest
>вместо $HTTP_GET_VARS юзай $_GET, вместо addslashes - mysql_escape_string
1. $_GET. Из-за того, что короче или есть еще причины?
2. addslashes - mysql_escape_string - опять же почему? Почитал мануал и не нашел особой разници.

Так, подправил. О FULTEXT index еще не читал, сейчас пойду, а пока вот:

PHP:
<?php 
require_once ("./class.php");

//решил что фр\орма должна быть видна всегда
echo "<form action=search.php method=get>
Что ищем: 
<input type=text name=s>
<select name='logic'>
<option value='OR'>искать любое из слов
<option value='AND'>искать все слова
</select>
<input type=submit value=' search '><br><br>
</form>";

if (isset($_GET['s'])) 
{ 
$s = $_GET['s'];
$logic = @$_GET['logic'];

$s = (substr(trim($s), 0, 64)); 
$word = preg_split("!\s!", $s);

//это а тот случай если $logic не установлен
if (($logic!="AND") && ($logic!="OR"))
	$logic = "OR";
	
$query = "SELECT s_id, name FROM arts WHERE atext LIKE '%";
$i = 0;
$c = count($word);
while ($i < $c) 
   {
  if (strlen($word[$i])>2)
  	if ($i == ($c-1))
  		$query .= addslashes($word[$i])."%'"; //если последнее слово
	else  
		$query .= addslashes($word[$i])."%' $logic atext LIKE '%"; //если будут еще слова
  $i++;	
  };
  
$result = query_sql($query); //query_sql() -  mysql_query() но уже с проверками
$r = mysql_numrows($result); //количество найденых строк

echo "<b>Искали:</b> <i>$s</i><br>";
echo "<b>Количество найденных статей: $r</b><br><br>";

while($row=mysql_fetch_array($result)) {echo "<a href=article.php?id=".$row['s_id'].">".$row['name']."</a><br>";}

}
 

?>
 

Фанат

oncle terrible
Команда форума
ты не сделал ничего из того, что я сказал.
смысл было заморачиваться...
 

SelenIT

IT-лунатик :)
Rus
1) $_GET - суперглобальный массив (автоматически доступен из любой функции)
2) addslashes некорректно работает при magic_quotes_sybase=On (редко, но бывает). А mysql_escape_string сама успела устареть - начиная с php 4.3.0 самый правильный вариант - [m]mysql_real_escape_string[/m] )
 

Rus

Guest
Сори, пропустил. Переделал с использованием implode():
PHP:
<?php 
require_once ("./class.php");

echo "<form action=search.php method=get>
Что ищем: 
<input type=text name=s>
<select name='logic'>
<option value='OR'>искать любое из слов
<option value='AND'>искать все слова
</select>
<input type=submit value=' search '><br><br>
</form>";

if (isset($_GET['s'])) 
{ 
$s = $_GET['s'];
$logic = @$_GET['logic'];

$s = (substr(trim($s), 0, 64)); 
$word = preg_split("!\s!", $s);

//это а тот случай если $logic не установлен
if (($logic!="AND") && ($logic!="OR"))
	$logic = "OR";
	
$query = "SELECT s_id, name FROM arts WHERE atext LIKE '%".implode("%' $logic atext LIKE '%", $word)."%'" ;

$result = query_sql($query); //query_sql() -  mysql_query() но уже с проверками
$r = mysql_numrows($result); //количество найденых строк

echo "<b>Искали:</b> <i>$s</i><br>";
echo "<b>Количество найденных статей: $r</b><br><br>";

while($row=mysql_fetch_array($result)) {echo "<a href=article.php?id=".$row['s_id'].">".$row['name']."</a><br>";}
}
?>

Но! Теперь нет addslashes(), а без него нельзя т.к. у меня magic_quotes_sybase=Off. Как бы красиво каждый элемент массива через эту функцию пропустить?
 

Фанат

oncle terrible
Команда форума
так нету и обрезания.
Добавь цикл обработки
PHP:
  foreach ($words as $k => $v) {
    if (strlen($v) < 3) unset($words($k));
    else $words[$k]=addslashes($v);
  }

Дальше. зачем ты выводишь форму эхом? Это же неудобно. ни кавычки токлом обязательные в форме, между прочим, не поставить, ни прочитать толком.
я тебе как написал форму нарисовать? вынеси её вообще переб первым пхп тегом

$s выводить имеет смысл через htmlspecialchars
 
Сверху