动态创建的WHERE子句PHP/MMySQL


Dynamically created WHERE clause PHP/MySQL

我正在动态生成MySQL查询的WHERE部分。到目前为止,我下面的代码运行得很好

请注意:_GET字符串在我的代码中的其他位置都经过了验证,但为了将此代码的长度控制在合理的范围内,我将它们直接放在下面。对于任何想做类似于我正在做的事情并将我的代码作为基础的人,请确保验证您的字符串以避免mysql注入。

  /* Loop through each column in the table */
        for ( $i=0 ; $i<count($aColumns) ; $i++ )
        {
             /* check if the column has been marked as searchable and that the param sent from the client contains data */
            if ( $_GET['bSearchable_'.$i] == "true" && $_GET['sSearch_'.$i] != '' )
            {
                if ( $sWhere == "" )
                {
                    $sWhere = "WHERE ";
                }
                else
                {
                    $sWhere .= " AND ";
                }

/* RANGE FILTER CODE - This part is not important to this question but included for completenes */
                $columnFilterValue = mysql_real_escape_string($_GET['sSearch_' . $i]);
                // check for values range
                $rangeSeparator = "~";
                if (!empty($rangeSeparator) && strstr($columnFilterValue, $rangeSeparator)) {
                    // get min and max
                     $columnFilterRangeMatches =  explode('~', $columnFilterValue);
                    // get filter
                    if (empty($columnFilterRangeMatches[0]) && empty($columnFilterRangeMatches[1]))
                        $sWhere .= " 0 = 0 ";
                    else if (!empty($columnFilterRangeMatches[0]) && !empty($columnFilterRangeMatches[1]))
                        $sWhere .= $aColumns[$i] . " BETWEEN '" . $columnFilterRangeMatches[0] . "' and '" . $columnFilterRangeMatches[1] . "' ";
                    else if (empty($columnFilterRangeMatches[0]) && !empty($columnFilterRangeMatches[1]))
                        $sWhere .= $aColumns[$i] . " < '" . $columnFilterRangeMatches[1] . "' ";
                    else if (!empty($columnFilterRangeMatches[0]) && empty($columnFilterRangeMatches[1]))
                        $sWhere .= $aColumns[$i] . " > '" . $columnFilterRangeMatches[0] . "' ";
                } else {

    /* Begin building WHERE clause */

        $sWhere = "WHERE (";
                $aORs = array();
                    for ( $i=0 ; $i<count($aColumns) ; $i++ )
                            {
                                if ( $_GET['bSearchable_'.$i] == "true" && $_GET['sSearch_'.$i] != '' )
                                        {
                                                    $value = $_GET['sSearch_'.$i];
                                                        array_push($aORs, $aColumns[$i]." IN ($value)");

                                        }
                            }
                $sWhere .= implode(" OR ",$aORs);   
        $sWhere .= ')';
                }
            }
        }

现在,这段代码的作用是接收从客户端发送的逗号分隔的值字符串,并基于这些值构建WHERE类。

  • $aColumns是一个数组,包含表中的列

示例:-

如果参数。。。

  • sSearch_1包含值1,3,5,6
  • sSearch_2包含值1,2,3
  • sSearch_4的值为4,5,6
  • 搜索6个cnt的值为7,8,9

然后,此代码将生成以下WHERE子句:

 WHERE genre_id IN (1,3,5,6) OR instruments IN (1,2,3) OR emotions IN (4,5,6) OR ratings IN (7,8,9)

这很好,但我想通过发送另一个字符串来使OR或AND动态,该字符串包含按正确顺序排列的OR和AND列表。

例如,如果$_GET['filtertype']=这样的字符串:-

OR,OR,AND

那么它应该返回:

WHERE genre_id IN (1,3,5,6) OR instruments IN (1,2,3) OR emotions IN (4,5,6) OR ratings IN (7,8,9)

正如您在上面的代码中所看到的,我目前正在通过内爆函数将OR注入到我的数组中。(以下重复代码的相关部分)

  $sWhere = "WHERE (";
                $aORs = array();
                    for ( $i=0 ; $i<count($aColumns) ; $i++ )
                            {
                                if ( $_GET['bSearchable_'.$i] == "true" && $_GET['sSearch_'.$i] != '' )
                                        {
                                                    $value = $_GET['sSearch_'.$i];
                                                        array_push($aORs, $aColumns[$i]." IN ($value)");

                                        }
                            }
                $sWhere .= implode(" OR ",$aORs); 
        $sWhere .= ')';

我如何修改它,以便在正确的循环的基础上依次添加正确的AND或or?

我不创建where字符串,而是首先创建一个包含where部分的数组。

$whereParts = array();
foreach($aColumns as $i => $column)
{
    <logic goes here>
    $whereParts[] = 'genre_id IN (1,3,5,6)'; // sample :)
}
$where = 'WHERE ' . implode(' OR ', $whereParts); // note the spaces around OR

那么用' AND ' 代替' OR '就很容易了

允许用户为所有where部件在AND和OR之间进行选择是很容易的,但如果您想为每个单独的项目进行选择,则不需要这样做。这也是一个逻辑问题。当用户指定a OR b AND c时,他想要(a OR b) AND c还是a OR (b AND c)