Php 基于发布变量构建MySQL查询

Php 基于发布变量构建MySQL查询,php,mysql,Php,Mysql,这似乎是一项简单的任务,但我很难找到一个我喜欢的解决方案。我找不到任何东西,除了笨拙之外,我什么也不想。以下是我的工作内容: 有一个搜索表单将变量发布到处理脚本。这些变量是查询数据的过滤器。根据用户的权限,可能会有更多或更少的变量进入,这取决于他们可以访问的过滤器。基本上,每个过滤器都引用表中的一个字段,这些字段是结果的来源。每个过滤器的一个选项也是ANY,因此不需要WHERE子句 构建查询字符串的好方法是什么。假设有四个变量返回:$firstname,$lastname,$age,$dob。但

这似乎是一项简单的任务,但我很难找到一个我喜欢的解决方案。我找不到任何东西,除了笨拙之外,我什么也不想。以下是我的工作内容:

有一个搜索表单将变量发布到处理脚本。这些变量是查询数据的过滤器。根据用户的权限,可能会有更多或更少的变量进入,这取决于他们可以访问的过滤器。基本上,每个过滤器都引用表中的一个字段,这些字段是结果的来源。每个过滤器的一个选项也是ANY,因此不需要WHERE子句

构建查询字符串的好方法是什么。假设有四个变量返回:$firstname,$lastname,$age,$dob。但只有部分用户可以通过$age和$dob进行筛选

$query = "SELECT * FROM people";
if(($firstname != 'ANY' && !empty($firstname)) ||
   ($lastname != 'ANY' && !empty($lastname)) ||
   ($age != 'ANY' && !empty($age)) ||
   ($dob != 'ANY' && !empty($dob))) {
    $query .= " WHERE";
}

if($firstname != 'ANY' && !empty($firstname)) {
    $query .= " firstname='$firstname'";
}
if($lastname != 'ANY' && !empty($lastname)) {
    if($firstname != 'ANY' || !empty($firstname)) {
        $query .= " AND";
    }
    $query .= " lastname='$lastname'";
}
...
等等。但在我看来,这只是愚蠢、可怕和可笑的低效。我使用的是稍微修改过的MVC模式,因此在搜索模型中为每个可能的过滤器构建方法是否有意义?

您可以扩展此功能:

我会这样做:

$query = "SELECT * FROM people"; $whereClause = " WHERE 1 = 1 "; if($firstname != 'ANY' && !empty($firstname)) { $whereClause .= " AND firstname='$firstname' "; } if($lastname != 'ANY' && !empty($lastname)) { $whereClause .= " AND lastname='$lastname' "; } $query .= $whereClause; 您也可以将所有语句收集到一个数组中,然后执行以下操作:

if (count($arr)>0) { $query = "$query WHERE ". implode(" AND ",$arr); }
下面是一些代码,可以将所有发布的变量拉到一起并将它们串在一起

foreach($_POST as $name=>$value){
    $arrFields[] = $name." = '".$value."'";
}
$sSql = "SELECT * FROM people WHERE 1 AND ".implode(" AND ",$arrFields);
或者,如果字段名与表名不同,或者希望在SQL中以不同的方式处理字段,则可以使用开关

foreach($_POST as $name=>$value){
    switch($name){
        case "firstname":
            $arrFields[] = "fName = '".$value."'";
            break;
        case "lastname":
            $arrFields[] = "lName = '".$value."'";
            break;
        case "age":
            $arrFields[] = "bioAge >= ".$value;
            break;
    }
}
$sSql = "SELECT * FROM people WHERE 1 AND ".implode(" AND ",$arrFields);

不幸的是,目前我没有使用任何类型的PDO;虽然这肯定是我正在调查的事情。我继承了一些代码,一次只能改变这么多。用户被重定向到:从未想过这样的方法。我仍然觉得有某种模式或我可以遵循的东西,但这至少会清理代码,这是一种更干净的方法。事实上,我能够从Nathan的开场白和这个回复中改进我的一些代码。我相信Nathan问题的一般答案是肯定的,PHP看起来有点复杂。对不起!我会继续关注-也许我错了。也许我应该看看PDO,根据其他发布的答案。当处理多个变量时,根据它们的值,最终结果会发生变化——不管发生什么,结果都会很复杂。区别在于它更容易阅读,而不是更混乱。我还在玩它-我真的觉得我还缺少一些东西。另一个不错的方法是将所有语句收集到一个数组中,然后只要count$arr>0{$query.=WHERE.inclode和,$arr;}我在我的回答中添加了内爆建议作为旁注,你可以这样做,但空间有限,指定字段而不是使用*。