繁体   English   中英

如何为 php 中的多个下拉过滤创建优化的 sql 查询?

[英]How to create an optimized sql query for multiple dropdown filtering in php?

我是 php 的新手,正在从事一个项目。 一开始有 2 个过滤器,我在编写具有 4 个条件的 sql 查询时并不担心。 但现在我有 8 个不同的下拉菜单,我需要为过滤器功能编写优化的 sql。 根据要写的条件,我需要写 256 个条件,这是最糟糕的主意。

这里的问题是,没有强制选择过滤的字段。 这让我在应用不同方法时遇到了更多问题。

有没有其他方法可以解决这个问题? 优化查询的最佳想法是什么。

示例代码

if($_REQUEST['action']=='action_report'){
   $v1 = $_POST['v1'];
   $v2 = $_POST['v2'];

  if(!empty($v1) && !empty ($v2)){
     $sql = "SELECT * FROM TABLE WHERE v1=$v1 AND v2=$v2 AND action='action_report'";
  }elseif(!empty($v1) && empty($v2)){
     $sql = "SELECT * FROM TABLE WHERE v1=$v1 AND action='action_report'";
  }elseif(empty($v1) && !empty($v2)){
     $sql = "SELECT * FROM TABLE WHERE v2=$v2 AND action='action_report'";
  }elseif(empty($v1) && empty($v2)){
     $sql = "SELECT * FROM TABLE WHEREAND action='action_report'";
  }
}

代码如下所示:

$sql = 'SELECT * FROM TABLE WHERE ';
$first = true;
foreach($_POST as $paramName => $value) {
    if ($first) {
        $sql .= "{$paramName}='{$value}'";
        $first = false;
        continue;
    }
    $sql .= " AND {$paramName}='{$value}'";
}

由于 $_POST 是传入变量的数组,您可以通过简单的 foreach 循环对其进行 go 并将其附加到 SQL 查询字符串。 第一个可能的参数不需要 AND 运算符,因此您必须以不同的方式处理它,这就是$first变量的用途。

但是这段代码存在 SQL 注入漏洞,因此最好将参数名称和值附加到 SQL 字符串中,如下所示:

$sql .= ' AND ' . mysqli_real_escape_string($connection, htmlspecialchars($paramName)) . "='" . mysqli_real_escape_string($connection, htmlspecialchars($value)) . "'";

您还将收到空值,您不想附加到 SQL 查询字符串。 所以最终的代码也需要处理这个问题,经过一些格式化后,它看起来像这样:

$sql = 'SELECT * FROM TABLE WHERE ';
$first = true;
foreach($_POST as $paramName => $value) {
    $protectedParamName = mysqli_real_escape_string($connection, htmlspecialchars($paramName));
    $protectedValue = mysqli_real_escape_string($connection, htmlspecialchars($value));

    if (empty($value)) {
        continue;
    }

    if ($first) {
        $sql .= "{$protectedParamName}='{$protectedValue}'";
        $first = false;
        continue;
    }

    $sql .= " AND {$protectedParamName}='{$protectedValue}'";
}

在示例中, $connection变量是 mysqli object:

$connection = new mysqli(
    $dbConfig['host'],
    $dbConfig['user'],
    $dbConfig['password'],
    $dbConfig['databaseName'],
    $dbConfig['port']
);

foreach($_POST as $paramName => $value)遍历每个 $_POST 数组值,因此如果您不希望在 SQL 查询中使用某些字段,那么您可以使用黑名单过滤,您可以在其中指定 $paramName 是否在黑名单中,那么您不会将其附加到 SQL 查询中。

例如:

$blackList = [
    'action'
];
foreach($_POST as $paramName => $value) {
    if (in_array($paramName, $blackList)) {
        continue;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM