我正在尝试在数据库中搜索 $_POST['search']
中传递的一个或多个关键字,但我无法循环遍历这些关键字。
代码修改自https://code-boxx.com/php-mysql-search/
我的脚本是:
$str = $_POST['search'];
$keywords = preg_split('/[\s]+/', $str);
$totalKeywords = count($keywords);
$query = "";
$i = 0;
while($keywords[i] != null)
{
$query .= " AND name LIKE %".$keywords[i]."%" ;
}
$stmt = $pdo->prepare("SELECT * FROM MYTABLE WHERE MATCH (name) AGAINST (?) ". $query ." ");
$stmt->execute([$_POST['search']]);
$results = $stmt->fetchAll();
理想情况下,搜索应如下所示:
SELECT * FROM MYTABLE WHERE MATCH (name) AGAINST (Keyword1 Keyword2 Keyword3) AND name LIKE '%Keyword1%' AND name LIKE '%Keyword2%' AND name LIKE '%Keyword3%
搜索页面:
<?php
if (isset($_POST['search'])) {
require "2.php";
}
?>
<!DOCTYPE html>
<html>
<body>
<!-- [SEARCH FORM] -->
<form method="post">
<input type="text" name="search" required/>
<input type="submit" value="Search"/>
</form>
<!-- [SEARCH RESULTS] -->
<?php
if (isset($_POST['search'])) {
if (count($results) > 0) {
echo $sql;
foreach ($results as $r) {
printf("<div>%s</div>", $r['name']);
}
} else {
echo "No results found";
}
}
?>
</body>
</html>
感谢任何帮助。
最佳答案
当您使用准备好的语句时,请避免将值直接注入(inject)查询语句中。你会达不到让他们做好准备的目的。
因此,首先您可以将语句分为两部分。
一是匹配
,二是where like
部分。
所以首先构建基本查询:
$sql = "SELECT * FROM MYTABLE WHERE 1=1"; // base query
从那里您可以在构建过程中附加 match against 和 where like 子句。
然后,创建与位的匹配:
MATCH (name) AGAINST (Keyword1* Keyword2* Keyword3* IN BOOLEAN MODE) // the ideal query
MATCH (name) AGAINST (? ? ? IN BOOLEAN MODE) // convert to question mark placeholders
要创建它,只需根据输入的数量将问号与空格内爆(粘合)即可:
$against_placeholder = implode(' ', array_fill(0, $totalKeywords, '?')); // = ? ? ?
并创建 where like 子句:
(name LIKE ? OR name LIKE ? OR name LIKE ?) // = like keyword1 or like keyword2 or like keyword3
所以在你的代码中:
$like_placeholder = implode(' OR ', array_fill(0, $totalKeywords, 'name LIKE ?'));
将它们拼凑在一起:
$against_placeholder = implode(' ', array_fill(0, $totalKeywords, '?'));
$like_placeholder = implode(' OR ', array_fill(0, $totalKeywords, 'name LIKE ?'));
$sql .= " AND MATCH (name) AGAINST ({$against_placeholder}) AND ({$like_placeholder})"; // build the query with placeholders
这将产生一个完整的查询语句,如下所示:
SELECT * FROM MYTABLE WHERE 1=1 AND (MATCH (name) AGAINST (? ? ? IN BOOLEAN MODE)) AND (name LIKE ? OR name LIKE ? OR name LIKE ?)
然后剩下的就是在执行中构建实际的有效负载。其余部分如下:
$sql = "SELECT * FROM MYTABLE WHERE 1=1"; // base query
$against_placeholder = implode(' ', array_fill(0, $totalKeywords, '?'));
$like_placeholder = implode(' OR ', array_fill(0, $totalKeywords, 'slug LIKE ?'));
$sql .= " AND (MATCH (slug) AGAINST ({$against_placeholder} IN BOOLEAN MODE)) OR ({$like_placeholder})"; // build the query with placeholders
// prep input
$against_keywords = array_map(function($value) {
return "{$value}*";
}, $keywords);
$where_keywords = array_map(function($value) {
return "%{$value}%";
}, $keywords);
$keywords = array_merge($keywords, $where_keywords);
$stmt = $pdo->prepare($sql);
$stmt->execute($keywords);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
关于php - 使用多个关键字搜索Mysql数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57983783/