返回

MySQL 表格搜索筛选难题:如何正确实现多条件筛选

mysql

MySQL 表格搜索筛选难题解析

针对用户提出的 MySQL 表格搜索筛选问题,症结在于筛选条件的处理方式,特别是 active_status 的筛选未能生效。现将问题拆解分析并给出切实可行的解决方案。

问题分析

该脚本旨在根据用户通过下拉菜单选择的职位(rank)和活跃状态(active_status)来过滤会员数据库表中的数据。脚本使用 $_REQUEST 变量接收表单数据。 结构上看,当只筛选职位(rank)时查询运行正常。但是当想要使用active_status来筛选结果时则不行,$search_status 未能正确应用到 SQL 查询。 细看代码发现:当两个下拉菜单都有值的情况下, SQL查询语句仅仅使用 $search_position 来查询。 而 当 $search_status 非空的情况下应该添加进 SQL 查询。 这会导致当选择 active status 进行筛选时,未能添加到SQL 语句中进行数据筛选。

解决方案一:正确构建 SQL 查询条件

问题的核心在于构建 SQL 查询语句时逻辑不严谨。 正确的做法是在判断两个筛选条件是否存在后, 依据条件逐个累加SQL语句片段。 需要修改 SQL 语句的构造逻辑,确保在有筛选条件时将其加入到查询语句中,且多个条件时正确拼接。

<?php
    include("./includes/connnect.php");

    $sql = "SELECT * FROM " . $SETTINGS["data_table"] . " WHERE committee_id > 0";

    if (!empty($_REQUEST["rank"])) {
        $rank = mysqli_real_escape_string($connection, $_REQUEST["rank"]);
        $sql .= " AND `rank` = '" . $rank . "'";
    }

    if (!empty($_REQUEST["active_status"])) {
        $active_status = mysqli_real_escape_string($connection, $_REQUEST["active_status"]);
        $sql .= " AND `active_status` = '" . $active_status . "'";
    }
    $sql_result = mysqli_query($connection, $sql) or die ('request "Could not execute SQL query" ' . $sql);

    ?>

操作步骤:

  1. 检查 $_REQUEST["rank"]$_REQUEST["active_status"]是否为空, 如果非空表示需要作为筛选条件。
  2. 通过 mysqli_real_escape_string() 函数处理接收到的值, 预防 SQL 注入。
  3. 将筛选条件拼接至 $sql 变量中。注意使用 and 连接多个条件。
  4. 执行拼接完成的 $sql 语句。

此方法在构造 SQL 查询时更清晰, 每个筛选条件独立处理,确保所有选择的筛选条件都能被加入 SQL 语句。

解决方案二:使用预处理语句(Prepared Statement)

预处理语句能有效地防止 SQL 注入,代码会更为安全和健壮。该方法更推荐在生产环境中使用。

<?php
include("./includes/connnect.php");

$sql = "SELECT * FROM " . $SETTINGS["data_table"] . " WHERE committee_id > 0";
$params = [];
$types = "";

if (!empty($_REQUEST["rank"])) {
    $sql .= " AND `rank` = ?";
    $params[] = $_REQUEST["rank"];
    $types .= "s"; // 's' 表示字符串
}

if (!empty($_REQUEST["active_status"])) {
    $sql .= " AND `active_status` = ?";
    $params[] = $_REQUEST["active_status"];
    $types .= "s";
}
    
$stmt = mysqli_prepare($connection, $sql);

if ($stmt === false) {
   die("Prepare failed: " . mysqli_error($connection));
}
// 动态绑定参数
if(!empty($params)){
   mysqli_stmt_bind_param($stmt,$types, ...$params);
}
    mysqli_stmt_execute($stmt);

    $result = mysqli_stmt_get_result($stmt);

?>

操作步骤:

  1. 构建 SQL 语句,使用 ? 作为占位符表示变量。
  2. 创建 $params 数组, 用于存放需要查询的变量, 创建 $types 字符串存放变量类型。
  3. 利用 mysqli_prepare 函数预处理SQL语句。
  4. 利用 mysqli_stmt_bind_param 绑定参数到占位符。
  5. 执行预处理语句,并获取结果。

这种方式通过占位符和类型绑定有效防止 SQL 注入,提供更高的安全保障。同时,代码的结构性更强,更易于维护。

额外的安全建议

使用预处理语句不仅为了代码安全,也为了应用的安全。始终对所有用户输入进行验证和清理,减少 SQL 注入的潜在风险。 在实践中应该采用一种合适你的代码的方式进行编写。 在涉及用户输入或外部数据时,时刻保持警惕。定期审查数据库结构,更新软件补丁,提升系统安全性。