准备好的语句未返回所需的多个结果

Prepared Statements not returning the required multiple results

我在 的帮助下完成了这个功能,但由于我只有一个搜索参数,所以做了一些更改。

function searchResult($con, $search) {
   $keywords = explode(" ", $search);
   $total_keywords = count($keywords);
   $myquery = "SELECT * FROM products WHERE name LIKE CONCAT('%',?,'%')";
      for ($i=1 ; $i < $total_keywords; $i++) {
          $myquery .= " OR name LIKE CONCAT('%',?,'%')";
      }
   $stmt = mysqli_stmt_init($con);
   //check if the statement is not prepared
   if (!mysqli_stmt_prepare($stmt, $myquery)) {
       header("location: search.php?errorid=stmt_failed");
       exit();
   }
   $typeparam = '';
   foreach ($keywords as $key => $value) {
       $typeparam .= 's';
   }
   $bind_param = array();
   $bind_param[] =& $typeparam;
   foreach ($keywords as $key => $value) {
       $bind_param[]=&$keywords[$key];
   }
   call_user_func_array(array($stmt,'bind_param'), $bind_param);
   mysqli_stmt_execute($stmt);
   $matches = mysqli_stmt_get_result($stmt);
   if ($searches = mysqli_fetch_assoc($matches)) {
       return $searches;
   } else {
       $result = false;
       return $result;
   }
   mysqli_stmt_close($stmt);
}

现在,我有一个名为 products 的 table,其中 table 我有:

Nikon Paint bucket

Bricks

Asian Paint 2 liter Blue finish

PVC pipe

当我只搜索 bricks 时,它是 return Bricks,类似地所有其他产品都是 returned。但是,通过搜索 bricks paint 它只有 returns Nikon Paint bucket,但它应该 return Bricks 以及Paint 都会导致 table。所以,有两个问题,一个是它没有考虑多个关键字。另一个问题是,它不会 return 两个具有相同关键字的结果。

此外,准备好的语句是防止 SQL 注入的最佳方法,但在搜索栏中使用它是否明智,因为 mysqli_real_escape_string() 似乎效率低下。还有其他方法可以制作安全的搜索栏吗?

你的函数 returns 结果集中只有一行。调用 mysqli_fetch_assoc() 只产生一行。

如果你想从结果集中获取所有行,你应该调用mysqli_fetch_all()。我已经清理了实现并使用了 mysqli_fetch_all() ,它会给你一个行数组。

function searchResult(mysqli $con, string $search): array
{
    $keywords = explode(" ", $search);
    $total_keywords = count($keywords);
    $myquery = "SELECT * FROM products WHERE name LIKE CONCAT('%',?,'%')";
    for ($i = 1; $i < $total_keywords; $i++) {
        $myquery .= " OR name LIKE CONCAT('%',?,'%')";
    }
    $stmt = mysqli_prepare($con, $myquery);
    mysqli_stmt_bind_param($stmt, str_repeat('s', $total_keywords), ...$keywords);
    mysqli_stmt_execute($stmt);
    $matches = mysqli_stmt_get_result($stmt);

    return mysqli_fetch_all($matches, MYSQLI_ASSOC);
}

不要忘记启用 mysqli error reporting

但是,如果可以的话,我强烈建议使用 PDO。 PDO 更容易使用。考虑使用 PDO 的相同功能:

function searchResult(PDO $con, string $search): array
{
    $keywords = explode(" ", $search);
    $total_keywords = count($keywords);
    $myquery = "SELECT * FROM products WHERE name LIKE CONCAT('%',?,'%')";
    for ($i = 1; $i < $total_keywords; $i++) {
        $myquery .= " OR name LIKE CONCAT('%',?,'%')";
    }
    $stmt = $con->prepare($myquery);
    $stmt->execute($keywords);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}