Автопредложение с использованием PHP/MySQL и Ajax

Поэтому я создал автоподсказку для своей поисковой системы, похожую на Google, используя PHP/MYSQL и Ajax. Если у моего MySQL есть 2 разных заголовка с одинаковым именем, как мне сделать так, чтобы только один из них отображался в автозаполнении? Например: у меня есть поле с title= ufc 131 и другое с title=ufc 131. Когда я ищу UFC 131, как мне показать только один из них?

Я использую код..

<?php
    include('conn.php');
    $str = strtolower($_GET['content']);
    if(strlen($str))
    {
        $sel = mysql_query("select * from Streams where title like '".trim($str)."%'");
        if(mysql_num_rows($sel))
        {
            echo "<table border =\"0\" width=\"100%\">\n";
            if(mysql_num_rows($sel))
            {
                echo "<script language=\"javascript\">box('1');</script>";
                while($row = mysql_fetch_array($sel))
                {
                    $country = str_ireplace($str,"<b>".$str."</b>",($row['title']));
                    echo "<tr id=\"word".$row['title']."\" onmouseover=\"highlight(1,'".$row['title']."');\" onmouseout=\"highlight(0,'".$row['title']."');\" onClick=\"display('".$row['title']."');\" >\n<td>".$country."</td>\n</tr>\n";
                }
            }
            echo "</table>";
        }
    }
    else
    {
        echo "<script language=\"javascript\">box('0');</script>";
    }
?>

person Mdkd    schedule 18.06.2011    source источник
comment
ваш скрипт очень уязвим для атак SQL-инъекций   -  person Ibu    schedule 18.06.2011
comment
хм? извините, я новичок в SQL-инъекциях   -  person Mdkd    schedule 18.06.2011
comment
никогда не доверяйте пользовательскому вводу. Всегда экранируйте строки от пользователей, прежде чем использовать их в запросах, и всегда экранируйте строки, прежде чем показывать их пользователям. Используйте mysql_real_escape_string(). Это не связано с вашей текущей проблемой, просто предупреждение.   -  person rid    schedule 18.06.2011
comment
Я поддерживаю это. Если пользователь, например, введет следующую «строку поиска», он удалит всю таблицу поисковых предложений.: '; DELETE * FROM Streams Итак, учитывая, насколько это просто, представьте, какое еще безумие может из этого получиться.   -  person Battle_707    schedule 18.06.2011


Ответы (2)


Что ж, вы можете использовать функцию DISTINCT, вы можете использовать функцию GROUP BY или даже поместить все результаты поиска в массив в PHP после получения их из MySQL, а затем использовать функцию array_unique() для фильтрации дубликатов.

Но ничто из этого не так эффективно, как убедиться, что база данных не содержит дубликатов. Я хочу сказать, что, поскольку вы делаете предложение, вы хотите, чтобы элемент 'SELECT' выполнялся как можно быстрее. Любой тип обмана, подобный тем, которые я перечислил выше, потребует комбинации большего количества времени, большего объема памяти и большего количества ЦП. Следовательно, вам нужно убедиться, что база данных находится в хорошем состоянии, чтобы операторы SELECT могли выполняться как можно более плавно. Хороший способ сделать это — сделать поле «заголовок» в таблице «Потоки» УНИКАЛЬНЫМ индексом. Однако лично у меня есть FULLTEXT-индекс в моем «поле предложений». Индекс UNIQUE гарантирует, что в базе данных не будет дубликатов, но все это позволяет вам избежать небрежного PHP-кода для вставки. Если вы используете правильный ПОЛНОТЕКСТНЫЙ поиск, вы можете выполнять ПОЛНОТЕКСТОВЫЙ поиск (ПОИСКПОЗ() ПРОТИВ()). Поскольку эти поиски используют индекс, они выполняются НАМНОГО быстрее. Ваш оператор запроса без типа индекса фактически будет использовать индекс.

Вдобавок ко всему, вы, вероятно, также захотите немного обновить свой код PHP (/ echo), потому что, хотя ваш код действительно мал, он написан неоптимально (что опять же, это то, что вы ХОТИТЕ убедиться, в случае поисковых предложений).

person Battle_707    schedule 18.06.2011
comment
вы можете сделать код для меня, как я понятия не имею? я просто хочу отфильтровать дубликаты - person Mdkd; 18.06.2011
comment
@Mdkd: Конечно, я могу сделать код для вас, но, как я уже сказал, вы не должны захотеть, чтобы эта ошибка исчезла из ЭТОЙ стороны вашей системы. Хотя это возможно, я НАСТОЯТЕЛЬНО рекомендую вам максимально упростить код на конце ‹i›SELECT‹/i› запроса. Вы хотите убедиться, что информация ‹i›введена‹/i› правильно. Чтобы помочь вам с этим кодом, мне нужно увидеть, как ваш код выглядит с этой точки зрения. - person Battle_707; 18.06.2011

ваш код должен быть переработан. Хороший способ самовнушения — использовать минимально возможный объем данных. Так что в этом случае вы можете использовать JSON.

include('conn.php');
$str = strtolower($_GET['content']);
$str = mysql_real_escape_string($str); // escape to prevent sql injection

Теперь для вашего запроса вы можете использовать ключевое слово GROUP BY в mysql, чтобы не было повторяющихся строк.

$sel = "SELECT title FROM Streams
        WHERE title LIKE '{$str}%'
        GROUP BY title 
        LIMIT 10";

Теперь для возвращаемых данных вы можете вернуть их в нотации объекта Javascript JSON.

$data = "{";
while($row = mysql_fetch_array($sel)) {
   $data .= '"title":"'.$row['title'].'",';
}
$data .= "}";

теперь вы можете повторить содержимое

echo $data;

В вашем javascript вы можете использовать библиотеку, например Jquery, чтобы упростить получение облегченных данных json.

Я надеюсь, что это поможет вам сделать очень хороший ящик для самовнушения.

person Ibu    schedule 18.06.2011
comment
Помимо моих возражений против функции DISTINCT для этой системы (прочитайте мой ответ), я согласен с Ибу в том, что данные JSON намного эффективнее в этом сценарии. Тем не менее, я бы предложил не писать код таким образом, а вместо этого использовать rawurlencode() для $row['title'] (а затем unescape() в JS) и поместить его в массив. Затем используйте функцию php json_encode() перед отправкой (а затем используйте JSON.parse() в JS). Это даст вам гораздо лучшую производительность во многих отношениях. - person Battle_707; 18.06.2011
comment
код, который вы указали для запроса, дает мне эту ошибку Предупреждение: mysql_num_rows(): предоставленный аргумент не является допустимым ресурсом результата MySQL в /vhosts/firemoon.me/httpdocs/script_page.php в строке 9 - person Mdkd; 18.06.2011