多个过滤器一起工作或独立工作

时间:2013-09-23 19:27:54

标签: php sql

我有一个页面,您可以根据个人资料信息过滤用户。

我有4个不同的过滤器,分别是“City”,“Age Above”,“Age Below”和“Gender”。

我以这种方式工作,将所有可能的组合作为if语句,以便所有过滤器可以单独或以任何组合方式工作:

if (isset($ageabove)
&& empty($agebelow)  
&& empty($gender)
&& empty($city)
)
{

$sql = mysqli_query($con, "select * from Users1 

WHERE age >= 1

");

}

这很有用,但它有很多组合,我担心这可能是一种效率低下的方法。

现在我决定再添加1个过滤器,总共有5个过滤器。这会增加'if'语句的指数级数,我想知道是否有更好的方法来实现这个目标?

如果我不够清楚,请告诉我。

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:1)

$query = "SELECT stuff FROM table WHERE foo=1 ";
if ($filter1) {
    $query .= "AND filter1 = $val";
}
if ($filter2) {
    $query .= "AND filter2 = $val";
}
// run query

这样的事情会起作用吗? (if (isset($filter1) && !empty($filter1)) ..)

答案 1 :(得分:1)

  1. 不要将age存储在数据库中。除非用户专门进入并编辑它,否则它们将是他们永远注册的任何年龄。存储他们的出生日期并随时计算年龄:

    SELECT DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age
    
  2. 我更喜欢在SQL查询中为动态条件执行此操作:

    $query = 'SELECT * FROM table';
    
    $conditions = array();
    $parameters = array();
    
    if( isset($_GET['cond1']) ) {
       $parameters[] = $_GET['cond1'];
       $conditions = 'column1 = ?';
    }
    if( isset($_GET['cond2']) ) {
       $parameters[] = $_GET['cond2'];
       $conditions = 'column2 = ?';
    }
    // etcetera...
    
    if( ! empty(conditions) ) {
      $query .= ' WHERE ' . implode(' AND ', $conditions);
      $sth = $db->prepare($query);
      $rs = $sth->(execute($parameters));
    } else {
      $sth = $db->prepare($query);
      $rs = $sth->(execute());
    }
    
    if( ! $rs ) { /* error message */ }
    // yadda yadda yadda
    

    这将为您构建如下查询:

    SELECT * FROM TABLE WHERE column1 = ? AND column2 = ? AND ... columnN = ?
    

    以及以正确的顺序将所有参数放入数组中。

  3. 但是,我可能对MySQLi的参数化有点不满。我是PDO的人。

答案 2 :(得分:0)

要使过滤器更具动态性,请将它们注册到数据库中,如下所示:

您可以创建一个model_filters表(例如在mysql中):

drop table if exists model_filters;
create table model_filters (
  id int not null auto_increment primary key,
  name varchar(80) not null,
  model varchar(80) not null,
  condition varchar(40) not null,
  created datetime,
  modified datetime,
  active boolean not null default 1,
  index model_filters (name)
);

因此,为特定模型创建一些过滤器:

INSERT INTO model_filters VALUES 
  ('Age Above'   , 'user' ,'age <= %filter'),
  ('Age Below'   , 'user' ,'age >= %filter'),
  ('City'        , 'user' ,'city ="%filter"'),
  ('Gender'      , 'user' ,'gender = "%filter"');

然后,根据您的模型获取过滤器:

SELECT id, name FROM model_filters WHERE model = 'user' AND active = 1

迭代此值并生成过滤器<select>

<select name="filters" id="filters">
  <option value="1">Age Above</option>
  <option value="2">Age Below</option>
  <option value="3">City</option>
  <option value="4">Gender</option>
</select>

<input type="text" name="value" id="value">

并且,您获取此信息,搜索选定的过滤器,然后执行您的查询

<?php 
// I'm using PDO
$statment = $pdo->prepare("SELECT * FROM model_filters WHERE id = :id");
$statment->bindValue(':id', $_POST['filters']);
$status = $statment->execute();
$result = null;
if ($status == true) {
  $result = $statment->fetchAll(PDO::FETCH_ASSOC);
}

if ($result == null) {
  // ERROR!
}

现在,组织值

/*
  $result['condition'] is equal (for example): "age <= %filter"
  After replace is = "age <= :filter"

  Obs.: replace for whatever you want, for example: ":filtername, :value, :whatever"
*/

$condition = str_replace('%filter', ':filter', $result['condition']);

$statment = $pdo->prepare("SELECT * FROM Users1 WHERE $condition");
$statment->bindValue(':filter', $_POST['value']);
$status = $statment->execute();
$result = null;
if ($status == true) {
  $result = $statment->fetchAll(PDO::FETCH_ASSOC);
}

获取$result,发送给您的视图,并迭代过滤后的用户。

完成!