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

Php 如何在select语句和where子句中包含(用户选择-动态)列?,php,mysql,Php,Mysql,我想让用户选择他们想看到和不想看到的字段 表:公司CID、cname、州、项目经理、现场主管、电气工程师、机械工程师、液压工程师等 注意:从project_manager到最后一列的所有列的值均为“是/否” 假设用户希望找到在新南威尔士州拥有项目经理和电气工程师的公司 查询将是: Select cid, cname, project_manager, elec_engg from companies where state='NSW' AND project_manager=

我想让用户选择他们想看到和不想看到的字段

表:公司CID、cname、州、项目经理、现场主管、电气工程师、机械工程师、液压工程师等

注意:从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';

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

  $builderworks = $POST_['builderworks'];
 $hydrolics = $POST_['hydrolics'];
然后使用所有字符串值从数据库中选择,确保首先使用mysql\u real\u escape\u string清理上面的POST数据

大概是

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


基本上,$builderworks等是在该字段中发布的任何内容,每次有人提交时都会存储在该字段中,因此,如果我在表单中选择字段builderworks为yes,那么当我点击submit时,$builderworks将等于yes,然后使用数据库查询比较每个字符串中存储的内容,因此如果$builderworks中有yes,则选择所有等于$builderworks的字段将选择所有等于yes的字段,如果我在表单中选择了no,则选择所有等于no的字段。

我假设您只是将所有参数相加。如果您可以为每个HTML设置名称,那么表单中的元素应该与您期望的列名完全相同,这应该可以正常工作。当您返回帖子时,假设搜索将表单作为帖子提交,您可以循环浏览帖子值。我将创建一个有效列数组作为白名单进行检查,以避免出现中断查询

下面是一个使用oldschool mysql escaping或you的示例,我会使用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;
您还可以添加一个循环检查,只检查'Yes'值,排除'No'值

正如下面注释中所述,mysql\u escape\u字符串$value不正确。。。毫无疑问,为了正确、安全地使用准备好的语句和pdo,您需要将代码更改为:

$sql='从公司中选择cid、cname、项目经理、电气工程师'; $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();

值上的预处理语句和参数值上的白名单都将使此查询安全。

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


按照通常的方式将数据从数据库提取到模型或其他结构中,然后根据需要在视图的渲染层中选择性地显示该结构的数据

请不要在你的帖子上签名。我甚至建议删除该图片-它不会真正为你的问题添加细节…-1,因为使用mysql\u escape\u字符串,特别是考虑到它的缺陷以及这个查询即使在你使用后仍然容易受到SQL注入的影响。准备好的语句也不能保证这一点。@雷,谢谢你的帮助。我有所有与MySQL表中的列匹配的HTML字段元素。我喜欢为where子句运行循环的方式,我想进一步扩展它。当Where子句中的字段名为“是”时,该列应与公司名称和位置一起显示。你有什么办法吗。例如,从branch='NSW'和elec_engg='YES'和hydraulics='YES'所在公司选择cid、cname、elec_engg、hydraulics;蒂亚·约书亚说得有道理,尽管他关于事先准备好的声明没有保护它的说法我不同意。我已经使用准备好的语句添加了一个PDO版本。如果有人能用这段代码显示SQL漏洞,请准确指出。至于要显示的动态列,我将遵循与上面相同的模式。。。获取列列表并将其放入名为$columnNames的数组中。然后再次循环遍历$\u POST数组,如果$\u POST['columnname']中的一个条目为'yes',则将'columnname'添加到$columnNames数组中。然后使用逗号分隔符对字符串调用内爆,以创建一个名为$columns的逗号分隔字符串。然后类似于:$sql=SELECT$columns$WHERECALLEASE的内容在编辑注释时被切断。这是最后的更新,如果你觉得有用的话,别忘了给我的答案投票!。创建一个名为$columnNames的空数组,并为公司添加列名
每个查询中使用的名称和位置。然后再次循环遍历$\u POST数组,如果$\u POST['columnname']中的条目为“是”,则将的名称添加到$columnNames数组中。循环完成后,使用逗号分隔符调用字符串内爆,以创建一个逗号分隔的字符串,名为$columns。然后将其粘合在一起,如:$sql=SELECT$columns$whereClause-1。这甚至没有试图阻止SQL注入,它甚至提到了mysql\u real\u escape\u string.can not read??'然后使用所有字符串值从数据库中进行选择,确保首先使用mysql_real_escape_string清理上面的帖子数据。我的代码只是一个简单的示例,用于向用户指出正确的方向,它不应该是他们需要做的事情的副本,因此我说清理帖子的,让你想知道你是否真的准备好了我所说的…………如果你要否决投票,至少有礼貌地说出原因。