【问题标题】:How to use wildcard in PDO multi-word query?如何在 PDO 多词查询中使用通配符?
【发布时间】:2013-03-24 02:15:17
【问题描述】:

我正在进行的项目需要多词搜索...就像搜索“Sprint Apple iPhone”的示例一样。如果这些单词中的任何一个与我的数据库中的列匹配,则必须显示整行的内容。

相信我现在已经从 SQL 注入中得到了保护,但可能是错误的。我现在要解决的主要问题是我一次只能搜索一个词,例如“Sprint”或“Apple”或“iPhone”,但如果我输入整个查询,则不会显示任何结果。

部分查询确实有效,例如“Sprin”或“Ap”或“iPho”……不知道我哪里出错了。我查看了 StackOverflow 上的几个示例,这些示例适用于单个单词查询,但找不到多个单词的解决方案。

感谢任何帮助!

<font size="+3" face="Verdana">xxxx</font>
<br><br>
<form name="form" action="xxxx.php" method="get">
<input type="text" name="q" size="60" />
<input type="submit" name="Submit" value="Search">
</form>

<table>

<?

$var = $_GET['q'];

try {
$conn = new PDO('mysql:host=localhost;dbname=xxxx', $username, $password);
$stmt = $conn->prepare("SELECT * FROM phones WHERE carrier LIKE :search OR        
manufacturer LIKE :search OR model LIKE :search");
$stmt->execute(array('search' => "%$var%"));

$result = $stmt->fetchAll();

if ( count($result) ) {
foreach($result as $row) {
echo "<tr>";
echo "<td>" .$row['carrier']. "</td>";
echo "<td>" .$row['manufacturer']. "</td>";
echo "<td>" .$row['model']. "</td>";
echo "</tr>";    
}
} 
else {
echo "No results found.";
}
} 
catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
?>
</table>  

【问题讨论】:

  • 我假设所有这些xxxx都不一样,请提供一些真实的字段名称。另外 :search 不用于每个 Like 是吗?
  • 我更新了字段以使其更具可读性。 :search 用于每个 LIKE,因为查询来自所有 3 列的相同搜索框。

标签: search pdo wildcard


【解决方案1】:

考虑构建查询后多词关键字的外观:

SELECT ... WHERE somefield LIKE '%apple iphone%'
                                  ^^^^^^^^^^^^

您不能简单地将一堆单词转储到 LIKE 块中并期望它起作用。充其量,你必须做一些按摩:

... WHERE somefield LIKE '%apple%' AND somefield LIKE '%iphone%'
                           ^^^^^                        ^^^^^^

但是对于任何“长”查询字符串,这会变得非常丑陋非常非常快。

为方便起见,您只需切换到fulltext index

... WHERE somefield MATCH(somefield) AGAINST ('apple iphone')          

【讨论】:

  • 谢谢。我得到了第二种方法,但它也带来了不相关的结果......例如,如果我放入 Sprint Apple,它会为其他运营商和任何其他 Sprint 手机带来 iPhone。这是我使用 LIKE 的部分原因,结果更加准确,但也许有办法改进这种方法的结果?另一个问题是 ft_min_word_ln 或其他问题,它不允许像 'LG' 这样的 2 个字母搜索。我也尝试过第一种方法,但无论我将 % 符号放在哪里,它都只能与一个单词一起使用。
【解决方案2】:

我自己解决了这个问题,它实际上不是使用代码的解决方案,而是在最初将它们插入数据库时​​将Carrier,Manufacturer和Model自动组合到我的数据库中的1列中,然后匹配该 1 列针对用户提供的搜索查询。

【讨论】:

  • 当手机插入到我的数据库中时,我只是将整个名称添加到 fullphonename 列中,例如“Sprint Apple iPhone”,然后只搜索该 1 列。新代码:$stmt = $conn->prepare("SELECT * FROM Phones WHERE fullphonename LIKE :search");
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-20
  • 2019-01-21
  • 1970-01-01
  • 2011-02-02
相关资源
最近更新 更多