php - 使用多个关键字搜索Mysql数据库

标签 php mysql pdo

我正在尝试在数据库中搜索 $_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/

相关文章:

php - 具有相同值的数字数组

php - Mysql 选择入数组

php - 我可以用查询结果填充 session 变量吗?

php - 在 CentOS 6 上,模型->保存函数强制将整数参数绑定(bind)到 varchar 列

php - PDO 查询在本地主机上工作,但在网络服务器上不工作——如何调试问题?

php - 将 SQL 函数作为 PDO 准备语句运行并返回值

php - 如何使用 PHP 解析 JSON 文件?

php - 使用 PHP set_time_limit() 防止 nginx 504 网关超时

Php Mysqli 持久连接错误

mysql - 如果条件为 true 则运行 MySQL 查询,否则运行另一个查询