Перейти к содержимому

Сервис обмена электронных валют


Скрипт поиска по сайту

#1 Kuchuluk

Kuchuluk
  • Пользователь
  • 315 сообщений
  • Репутация: 5
0

Отправлено 07 Апрель 2013 - 21:30

делаю поиск по сайту. пользователь вводит имя или фамилию человека, которого хочет найти
код такой
public function search()
{
  if (!empty($_POST["query"]))
  {
   $query = trim($_POST["query"]);
   $query = strip_tags($query);
   //$query = mysql_real_escape_string($query);
   $query = addslashes($query);
   $query = htmlspecialchars($query);
   if (strlen($query) < 4)
   {
    echo "<p class='error_regist'>Слишком короткий поисковый запрос</p>";
   }
   elseif (strlen($query) > 40)
   {
    echo "<p class='error_regist'>Слишком длинный поисковый запрос. Поисковый запрос<br> должен быть не более 40 символов.</p>";
   }
   else
   {
    $preg = preg_match("#\s#",$query);// проверяю есть ли пробел, то есть одно или несколько слов ввел пользователь
    if ($preg == 1)
    {
	 echo "est";
	 $words = explode(" ",$query);
	 $sql_text = "SELECT * FROM users WHERE "; //Начало запроса
	 foreach ($words as $value)
	 {
	  // добавляем в $sql-запрос
	  $sql_text .= 'first_name LIKE "%'.$svalue.'%" OR login LIKE "%'.$svalue.'%" or ';
	 
	 }
	 // удаляем лишний "or" в конце строки
	 $sql_text = preg_replace('# or $#', '', $sql_text);
	 echo $sql_text;
	 $sql = mysql_query($sql_text);
	 $sqlt = mysql_fetch_assoc($sql);
	 return $sqlt;
    }
    else
    {
	 echo "net";
    }
   }
  }
}
проверил что попадает в сам запрос командой echo $sql_text; и вывелось SELECT * FROM users WHERE first_name LIKE "%%" OR login LIKE "%%" or first_name LIKE "%%" OR login LIKE "%%"
почему между %% ничего нет?

 

 

  • 0

#2 fedornabilkin

fedornabilkin
  • Пользователь
  • 696 сообщений
  • Репутация: 91

Отправлено 08 Апрель 2013 - 09:29

У тебя в фориче $value, а вставляешь ты в запрос $svalue, скорее всего поэтому.
Но я делал вот так однажды
//=== search
if( $_POST['action'] == 'search' ){

 
  $search = $_POST['search'];
 
  $search = trim($search); // пробелы слева, справа
  $search = substr($search, 0, 20); // порезать
  $search = addslashes($search); // экранирование
  $search = htmlspecialchars($search); // тэги
  if( $search == '' OR strlen($search) < 2 ){
   exit("Начните вводить запрос");
  }
 
  $search = '*' . $search . '*';
 
  $sql = "SELECT * FROM `users` WHERE MATCH(`soname`, `name`) AGAINST('$search'  IN BOOLEAN MODE)";
  $query = $db->query($sql);
  if( $db->num_rows($query) > 0){
	 while( $row = $db->get_row($query) ){
    $html .= '<a href="/udata/'.$row['id'].'/">'.$row['soname'].' '.$row['name'].'</a>';
	 }//
	 exit($html);
	
  }else{
	 exit("Нет результатов");
	 //exit($sql);
  }

}
Но у меня заточено под ajax, поэтому смотри на сам запрос.
  • 0
Как часто в горестной разлуке,В моей блуждающей судьбе, ФО, я думал о тебе.


#3 matroskin8

matroskin8
  • Пользователь PRO
  • 767 сообщений
  • Репутация: 143

Отправлено 08 Апрель 2013 - 10:08

почему между %% ничего нет?

С кавычками в этих двух строках разберитесь:
$sql_text .= 'first_name LIKE "%'.$svalue.'%" OR login LIKE "%'.$svalue.'%" or ';
...
$sql_text = preg_replace('# or $#', '', $sql_text);
Запрос - в двойных кавычках, строковые значения - в одинарных. В том числе и маркеры (%) должны быть заключены в одинарные кавычки, поскольку являются составляющими значения. Где-то так примерно должно выглядеть:
$sql_text .= "first_name LIKE '%{$svalue}%' OR login LIKE '%{$svalue}%' or ";
...
// то же самое и дальше
А вообще, полнотекстовый поиск работает на порядок быстрее, благодаря использованию индексов, каковые не использует оператор LIKE.
  • 1


#4 isvetlichniy

isvetlichniy
  • Пользователь
  • 619 сообщений
  • Репутация: 93

Отправлено 08 Апрель 2013 - 11:56

почему между %% ничего нет?

ответ однозначно в $value и $svalue

будь внимательнее
  • 0

#5 Kuchuluk

Kuchuluk
    Topic Starter
  • Пользователь
  • 315 сообщений
  • Репутация: 5

Отправлено 08 Апрель 2013 - 16:11

С кавычками в этих двух строках разберитесь:

спасибо, исправил. теперь вызываю этот метод на странице
if (isset($_POST["search"]))
  {
   $f = $base->search();
   //var_dump($f);
   $fs = mysql_fetch_assoc($f);
   //var_dump($fs);
   $city_name = $base->getOnce("kz_city","city_name",$fs["basic_city"]);
    $src = $us_info->selAva($fs["login"]);
    $text = "<div id='one_club'><img src=../party/".$src." class='float-left'>
    <p style='margin-left:20px; float:left'><a href='index.php?login=".$fs["login"]."' style='font-size:14px'>"
    .$fs["first_name"]."<br>".$fs["login"]."</a></p>
    <p style='margin-left:70%'><a href='clubs.php?c=".$fs["basic_city"]."' style='font-size:11px'>".$city_name."</a></p></div>";
   echo $text;
  }
но выводится только информация об одном пользователе. а на сайте с такой фамилией и именем их двое

Но я делал вот так однажды

  $sql = "SELECT * FROM `users` WHERE MATCH(`soname`, `name`) AGAINST('$search'  IN BOOLEAN MODE)";

А вообще, полнотекстовый поиск работает на порядок быстрее, благодаря использованию индексов, каковые не использует оператор LIKE.

для этого в базе данных надо же индексировать эти данные? или не обязательно?
  • 0

#6 matroskin8

matroskin8
  • Пользователь PRO
  • 767 сообщений
  • Репутация: 143

Отправлено 08 Апрель 2013 - 16:26

Смотрим что возвращает Ваш метод:
$sqlt = mysql_fetch_assoc($sql);
		 return $sqlt;
Итак, что? Правильно, 1 ряд результата запроса. Для того, чтобы вернуть все ряды, необходимо пройтись по результату в цикле... например так:
$data = array();
while($sqlt = mysql_fetch_assoc($sql)){
$data[] = $sqlt;
}
		 return $data; // возвращаем массив всех результатов

для этого в базе данных надо же индексировать эти данные? или не обязательно?

Обязательно, поскольку полнотекстовый поиск в своей работе использует полнотекстовый индекс. Индексирование полей несколько замедляет изменение данных таблицы, но зато их выборка становится практически мгновенной даже на очень больших массивах данных... чего не скажешь о поиске оператором LIKE, который подходит для относительно небольших массивов данных и небольших текстовых полей (CHAR / VARCHAR).
  • 0


#7 Kuchuluk

Kuchuluk
    Topic Starter
  • Пользователь
  • 315 сообщений
  • Репутация: 5

Отправлено 08 Апрель 2013 - 19:16

тогда вывод информации нужно тоже в цикле выводить? во здесь

if (isset($_POST["search"]))
{
$f = $base->search();
$city_name = $base->getOnce("kz_city","city_name",$f["basic_city"]);
$src = $us_info->selAva($f["login"]);
$text = "<div id='one_club'><img src=../party/".$src." class='float-left'>
<p style='margin-left:20px; float:left'><a href='index.php?login=".$f["login"]."' style='font-size:14px'>"
.$f["first_name"]."<br>".$f["login"]."</a></p>
<p style='margin-left:70%'><a href='clubs.php?c=".$f["basic_city"]."' style='font-size:11px'>".$city_name."</a></p></div>";
echo $text;
}
все это в цикл загнать, да?
  • 0

#8 matroskin8

matroskin8
  • Пользователь PRO
  • 767 сообщений
  • Репутация: 143

Отправлено 09 Апрель 2013 - 09:20

Информация из БД складывается в массив. Ну а затем эта информация из массива выводится на странице в нужном виде. Понятно, что для получения информацию из массива, нужно пройтись по этому массиву в цикле, выбирая один элемент за другим.

все это в цикл загнать, да?

Не все, а только то, что попадает, насколько я понимаю, в переменную $f. Можно распечатать этот объект, чтобы понять как с ним работать:
print_r($f);

  • 0


#9 Kuchuluk

Kuchuluk
    Topic Starter
  • Пользователь
  • 315 сообщений
  • Репутация: 5

Отправлено 09 Апрель 2013 - 18:35

Не все, а только то, что попадает, насколько я понимаю, в переменную $f. Можно распечатать этот объект, чтобы понять как с ним работать:

с помощью этой функции print_r($f); теперь попало все, что нужно, два массива с данными двух пользователей

теперь вставил все в цикл
if (isset($_POST["search"]))
  {
   $f = $base->search();
   foreach ($f as $pep_info)
   {
   $i = 0;
   $city_name = $base->getOnce("kz_city","city_name",$f[$i]["basic_city"]);
   $src = $us_info->selAva($f[$i]["login"]);
    $text = "<div id='one_club'><img src=../party/".$src." class='float-left'>
    <p style='margin-left:20px; float:left'><a href='index.php?login=".$f[$i]["login"]."' style='font-size:14px'>"
    .$f[$i]["first_name"]."<br>".$f[$i]["login"]."</a></p>
    <p style='margin-left:70%'><a href='clubs.php?c=".$f[$i]["basic_city"]."' style='font-size:11px'>".$city_name."</a></p></div>";
   echo $text;
   $i++;
   }
выводится два блока div с информацией о пользователе, но информация только об одном в обоих. хотя в $f попал массив с двумя
  • 0

#10 Kuchuluk

Kuchuluk
    Topic Starter
  • Пользователь
  • 315 сообщений
  • Репутация: 5

Отправлено 09 Апрель 2013 - 19:07

а всё, исправил. счетчик $i надо было вне цикла задавать
  • 0

robot

robot
  • Пользователь PRO
  • 2 652 сообщений
  • Репутация: 85


Оформление форума – IPBSkins.ru