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

时间:2012-01-22 23:36:57

标签: php mysql

我希望用户选择他们想要查看的字段以及他们不想看到的字段。

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

注意:project_manager到最后一列的所有列都具有值'Yes / No'

让我们说用户希望找到在新南威尔士州拥有项目经理和电气工程师的公司。

查询将是:

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';

3 个答案:

答案 0 :(得分:0)

只需将每个字段的结果放入一个字符串中,就像

一样
  $builderworks = $POST_['builderworks'];
 $hydrolics = $POST_['hydrolics'];

然后只需使用所有字符串值从数据库中选择,只需确保使用mysql_real_escape_string首先清理上面的POST数据。

类似

SELECT jobname FROM jobtable WHERE hydrolics='$hydrolics' AND $builderworks='$builderworks' 
等等

所以基本上$ builderworks等是在该字段中已经发布的内容,每次有人提交时都存储在内部,所以如果我去了表单,选择字段builderworks为yes,$ builderworks将等于是,当我点击提交,然后使用数据库查询比较每个字符串中存储的内容,那么如果$ builderworks在其中有肯定,则选择所有等于$ builderworks的字段将选择所有等于yes的字段,或者如果我有则等于否表格中没有选择。

答案 1 :(得分:0)

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

这是一个使用oldschool 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;

您还可以仅为“是”的值添加循环检查,并排除“否”值...

如下面的注释中所述,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();

关于值的预准备语句和参数值上的白名单都将使此查询安全。

答案 2 :(得分:0)

不要在数据库层上执行此操作。对于安全性,稳定性和可维护性而言,这是一个非常非常糟糕的想法。分开你的顾虑。您的数据访问层不应该依赖于您的用户权限,绝对不应该依赖于您的视图。

像往常一样从数据库中提取数据(进入“模型”或其他结构),然后根据需要选择性地在渲染层中显示该结构的数据(“视图”)。