准备好的语句未返回所需的多个结果
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);
}
我在
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);
}