【问题标题】:AutoSuggest Using PHP/MySQL & Ajax使用 PHP/MySQL 和 Ajax 的 AutoSuggest
【发布时间】:2011-09-17 15:15:12
【问题描述】:

所以我使用 PHP/MYSQL 和 Ajax 为我的搜索引擎创建了一个类似于 google 的自动提示。如果我的 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>";
    }
?>

【问题讨论】:

  • 你的脚本很容易受到sql injection attacks的攻击
  • 嗯?对不起,我是 sql 注入的新手
  • 永远不要相信用户输入。在查询中使用它们之前总是从用户那里转义字符串,并且在将它们显示给用户之前总是对字符串进行转义。使用mysql_real_escape_string()。这与您当前的问题无关,只是一个警告。
  • 我支持这个。例如,如果用户在“搜索字符串”之后键入,它将删除整个搜索建议表。:“'; DELETE * FROM Streams” 所以,考虑到这有多简单,想象一下这会发生什么其他疯狂。

标签: php mysql ajax autosuggest


【解决方案1】:

嗯,你可以使用 DISTINCT 函数,你可以使用 GROUP BY 函数,或者你甚至可以在 PHP 中将所有搜索结果从 MySQL 中获取,然后使用 array_unique() 函数进行过滤删除重复项。

但没有一个比确保数据库不包含任何重复项更有效。我的意思是,既然您提供了建议,您希望“SELECT”元素尽可能快地运行。任何类型的诡计,比如我上面列出的那些,都需要更多的时间、更多的内存和更多的 CPU。因此,您要做的是确保数据库处于良好状态,以便 SELECT 语句尽可能顺畅。一个很好的方法是让你的'Streams'表中的'title'字段成为唯一索引。但是,我个人拥有的是我的“建议字段”上的 FULLTEXT 索引。 UNIQUE 索引将确保数据库中肯定不会有任何重复,但它所做的一切让您摆脱了用于插入的草率 PHP 代码。如果您使用正确的 FULLTEXT 搜索,则可以进行 FULLTEXT 搜索 (MATCH() AGAINST())。由于这些搜索使用索引,它们的执行速度要快得多。您的查询语句将在没有索引类型的情况下实际使用索引。

除此之外,您可能还想稍微更新一下您的 PHP (/echo) 代码,因为尽管您的代码非常小,但它并不是以最佳方式编写的(这也是您想要确保的,在搜索建议的情况下)。

【讨论】:

  • 你能帮我做代码吗,因为我不知道吗?我只想过滤掉重复项
  • @Mdkd:当然我可以为你编写代码,但是就像我说的,你不应该想让这个 bug 离开你系统的这一端。尽管有可能,但我强烈建议您使查询 SELECT 端的代码尽可能简单。您要确保信息正确输入。为了让我帮助您编写该代码,我需要从该角度查看您的代码是什么样的。
【解决方案2】:

您的代码需要修改。 进行自动建议的一个好方法是使用尽可能少的数据量。 所以在这种情况下你可以使用JSON

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

现在你的查询,你可以在 mysql 中使用 GROUP BY 关键字来避免重复行

$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 数据

我希望这可以帮助您制作一个非常好的自动提示框

【讨论】:

  • 除了我反对这个系统的 DISTINCT 函数(阅读我的回答)之外,我同意 Ibu 的观点,即 JSON 数据在这种情况下效率更高。但是,我建议不要以这种方式编写代码,而是将 rawurlencode() $row['title'] (然后在 JS 中使用 unescape() )并将其放入数组中。然后在发送之前使用 php 函数 json_encode() (然后在 JS 中使用 JSON.parse() )。这将在许多方面为您提供更好的性能。
  • 您为查询输入的代码给了我这个错误警告:mysql_num_rows():提供的参数不是在线 /vhosts/firemoon.me/httpdocs/script_page.php 中的有效 MySQL 结果资源9
猜你喜欢
  • 2012-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-09
相关资源
最近更新 更多