一尘不染

如何在PHP中准备好的mysqli查询中忽略参数?

mysql

我有一个准备好的mysqli查询,如下所示:

$query = $database->prepare("SELECT * FROM items WHERE inStock > ? AND size < ? AND name LIKE ?");            
$query->bind_param('iis', $inStock, $size, $name);              
$query->execute();

WHERE子句中有许多条件可以过滤结果。问题在于,这些参数以搜索形式提供,并且不是必需的。例如,某人可以同时使用名称,或仅使用大小和名称,或使用大小,名称和inStock进行搜索。

我需要某种方式来调整查询,以便仅提供所需的参数。我能想到的唯一解决方案是制作一个巨大的if..else结构,其中存在具有所有搜索选项组合的预先准备好的查询,但是由于有成千上万的组合,所以这是不可能的。

我能想到的唯一实际可行的解决方案是使用未准备好的查询,在此情况下,我将条件与诸如 $query .= "AND name LIKE '%".escapestuff($_POST['name'])."%'"

但这很丑陋,我非常想保留准备好的查询系统。


阅读 257

收藏
2020-05-17

共1个答案

一尘不染

您可以建立条件列表,然后将绑定值和类型添加到列表中,这里是一个快速的模型,它使用了您引用的两个字段…

$data = [];
$params = "";
$where = [];
if ( !empty($name)) {
    $data[] = $name;
    $params.="s";
    $where[] = "name like ?";
}
if ( !empty($size)) {
    $data[] = $size;
    $params.="i";
    $where[] = "size < ?";
}
$sql = "SELECT * FROM items";
if ( count($where) > 0 ){
    $sql .= " where ". implode ( " and ", $where);
}
$query = $database->prepare($sql);
$query->bind_param($params, ...$data);
$query->execute();

请注意,bind_param()使用...可以让您传递数组而不是各个字段。

2020-05-17