php - 如何在 select 语句和 where 子句中包含(用户选择的 - 动态)列?

标签 php mysql

我希望用户可以选择他们想看的和不想看的字段。

表:公司(cid、cname、state、project_manager、site_supervisor、elec_engg、mech_engg、hydraulics、.....)

注意:从 project_manager 到最后一列的所有列的值为“是/否”

假设用户想要查找在新南威尔士州拥有项目经理和电气工程师的公司。

查询将是:

Select cid, cname, project_manager, elec_engg  
from companies  
where state='NSW'  
    AND project_manager='Yes'  
    AND elec_engg ='Yes';

我想知道如何使搜索动态化。以 HTML 格式显示所有职位,每个职位旁边都有复选框和搜索按钮。如下所示。

查询:

select cid, cname, (dynamic user input of columns) 
from companies  
where state="NSW"  
    AND Dynamic input column1 ='Yes'  
    and Dynamic input column2 ='Yes'  
    AND Dynamic input column3 ='Yes'.....  
    AND Dynamic input columnn ='Yes';

最佳答案

我假设您只是将所有参数放在一起。如果您可以为每个 HTML 设置名称,那么表单中的元素将完全符合您对列名称的期望,这应该可以工作。当您收到帖子时(假设搜索将表单作为帖子提交),您可以遍历帖子值。我会创建一个有效列数组来作为白名单进行检查,以避免查询中断。

这是一个使用旧式 mysql 转义的示例,或者您可以理解,但我真的会使用 PDO 和准备好的语句来填充查询的值。关键是在动态创建 SQL 时保护您的 where 参数和值。如果您正在使用 PDO 并希望看到它,请给我留言,但这将为您提供一个起点:

$sql = 'SELECT cid, cname, project_manager, elec_engg FROM companies ';
$whereClause =  null;   

//whitelist of valid where clause parameters
$validParams = array('site_supervisor', 'elec_engg', 'mech_engg', 'hydraulics');

foreach($_POST as $key=>$value){
    if(array_search($key, $validParams)!==false){ //make sure you use !== and not !=
        if(empty($whereClause)){
            $whereClause = " WHERE ";
        }else{
          $whereClause .= " AND ";
        }

        //IMPORTANT: use whatever you're db needs to escape things or use prepare
        //statement replacement
        $whereClause .= "$key='".mysql_escape_string($value)."' "; 
    }
}
$sql = $sql.$whereClause;
echo $sql;

您还可以为"is"值添加循环检查并排除“否”值...

如下评论中所述,mysql_escape_string($value) 是错误的...毫无疑问,要使用准备好的语句和 pdo 正确安全地执行此操作,您需要将代码更改为:

$sql = 'SELECT cid, cname, project_manager, elec_engg FROM companies '; $whereClause = null;

//whitelist of valid where clause parameters
$validParams = array('site_supervisor', 'elec_engg', 'mech_engg', 'hydraulics');

foreach($_POST as $key=>$value){
    if(array_search($key, $validParams)!==false){ //make sure you use !== and not !=
        if(empty($whereClause)){
            $whereClause = " WHERE ";
        }else{
          $whereClause .= " AND ";
        }

        //IMPORTANT: use whatever you're db needs to escape things or use prepare
        //statement replacement
        $whereClause .= " $key=:$key "; 
    }
}
$sql = $sql.$whereClause;
$db = new PDO($someDsnString);  
$statement = $db->prepare($sql);

foreach($_POST as $key=>$value){
    if(array_search($key, $validParams)!==false){ //make sure you use !== and not !=
    $statement->bindValue(":$key", $_POST[$key]);
    }
}       
$statement->execute();
$result = $statement->fetchAll();

值的准备语句和参数值的白名单都将使该查询安全。

关于php - 如何在 select 语句和 where 子句中包含(用户选择的 - 动态)列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8965747/

相关文章:

php - 在 WHERE 子句中使用变量

php - 用它在 php 中的当前值更新 MySql 值

mysql - where 子句中查询的查询性能问题

php - 关联数组到 JSON

php exec 没有按预期工作

php - Laravel 找到表内缺失的行

php - 使用 ARC2 PHP 库的 SPARQL INSERT

php - 如何使用 PHP 在行范围内显示 mysql 数据?

php - mysql查询偶尔什么都不返回

mysql - 如何故意创建长时间运行的 MySQL 查询