我希望用户选择他们想看到的字段和不想看到的域。
表:公司(cid、cname、state、project_manager、site_supersvisor、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';
我假设您只是将所有参数进行AND运算。如果您可以将表单中的每个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;
您还可以添加仅针对"Yes"值的循环检查,并排除"No"值。。。
正如下面在评论中所指出的那样,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();
准备好的值语句和参数值的白名单都将确保此查询的安全性。
只需将每个字段的结果放入一个字符串中,因此类似
$builderworks = $POST_['builderworks'];
$hydrolics = $POST_['hydrolics'];
然后只需使用所有字符串值从数据库中进行选择,只需确保首先使用mysql_real_eescape_string清除上面的POST数据。
所以像这样的东西
SELECT jobname FROM jobtable WHERE hydrolics='$hydrolics' AND $builderworks='$builderworks'
等等
所以基本上$builderworks等是张贴在该字段中的任何东西,每次有人提交时都会存储在里面,所以如果我去表单,选择字段builderworks为yes,那么当我点击submit时,$builderworks将等于yes,然后使用数据库查询比较每个字符串中存储的任何东西,选择所有等于$builderworks的字段将选择所有等于yes的字段,或者如果我在表单中选择了no,则选择所有等于no的字段。
不要在数据库层上执行此操作。对于安全性、稳定性和可维护性来说,这是一个非常非常糟糕的想法。分开你的顾虑。您的数据访问层不应依赖于用户的权限,也不应绝对依赖于您的视图。
按照通常的方式从数据库中提取数据(提取到"模型"或其他结构中),然后根据需要在渲染层中选择性地显示该结构的数据("视图")。