如何以最有效的方式使用通配符?

时间:2013-08-29 14:45:01

标签: php mysql search wildcard

我有一个我正在处理的快速搜索条形码,它看起来像这样:

searchbar.php:

<form method="post" action="search.php">
<input type="text" name="search" />
<input type="submit" />
</form>

的search.php:

<?php
include("config.php");
$search = mysql_real_escape_string($_POST['search']);
$data = mysql_query("SELECT * FROM shop WHERE name LIKE '%$search%' OR id LIKE '%$search%' OR description LIKE '%$search%' OR keywords LIKE '%$search%' ORDER BY id DESC ") or die(mysql_error());
while ($info = mysql_fetch_array($data)) {
    $name = stripslashes($info['name']);
    $desc = stripslashes($info['description']);
    Print "<h3><a href=\"result.php?product=".$name."\">".$name."</a>: <font color=\"#cd0000\">".$desc."</font></h3><br>";
}
echo $name;
?>

result.php:

<?php
$result = $_GET['product'];
echo $result;
?>

现在我的问题是我的搜索中使用了通配符。说有人搜索两个词,“foo bar。”我拥有它的方式必须完全按照这个顺序,它们之间有一个空间可以出现。有没有办法在我的搜索参数中,如果单词“foo”和“bar”在任何地方(即使不是彼此相邻),结果会显示出来?此外,如果单词的顺序按顺序颠倒,“bar foo”(再一次甚至不是彼此相邻),我希望它能够工作。

3 个答案:

答案 0 :(得分:0)

由于您正在进行LIKE '%...%'匹配,您应该意识到MySQL不能使用索引来执行此类搜索,并且您每次都会强制进行全表扫描。正如您所提到的,如果用户输入foo bar,您将搜索完整的短语。

您可以使用foo bar作为搜索词来获得一些替代方案:

1)预处理搜索词,以便搜索词组中的每个“词”成为自己的匹配集,例如

WHERE (
        field1 LIKE '%foo%' OR field2 LIKE '%foo%' OR ...
     OR field1 LIKE '%bar%' OR field2 LIKE '%bar%' OR ...
)

2)切换到使用全文索引,将查询减少到

WHERE MATCH(field1, field2, ...) AGAINST ('foo bar')

答案 1 :(得分:0)

您可以使用此

从查询中删除空格
str_replace('  ' , '' , $string );

这里我们在第一个参数中查找空格,在第二个参数中替换为空,并在第三个参数中加载我们想要处理的字符串。

希望这会有所帮助。

答案 2 :(得分:0)

如果要搜索每个单独的项目,则必须单独搜索它们。 这段代码(未经测试)应该

$search = explode(' ',$_POST['search']);
$query = "SELECT * FROM shop WHERE (";
foeach($search as $value){
    $value = mysql_real_escape_string($value);
    $whereClauses[] = "name LIKE '%$value%' OR id LIKE '%$value%' OR description LIKE '%$value%' OR keywords LIKE '%value%'";
}
$query.= implode(' OR ',$whereClauses) .') ORDER BY id DESC ';

$data = mysql_query($query) or die(mysql_error());
while ($info = mysql_fetch_array($data)) {
    $name = stripslashes($info['name']);
    $desc = stripslashes($info['description']);
    Print "<h3><a href=\"result.php?product=".$name."\">".$name."</a>: <font color=\"#cd0000\">".$desc."</font></h3><br>";
}

请注意,这是一个非常糟糕的方法,因为由于MySQL无法使用索引,因为要找到项目之前和之后的通配符,因此需要进行全表扫描。