0

我有一个页面,您可以在其中按个人资料信息过滤用户。

我有 4 个不同的过滤器,分别是“城市”、“年龄以上”、“年龄以下”和“性别”。

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

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

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

WHERE age >= 1

");

}

这行得通,但它有很多组合,我确实担心这可能是一种低效的方法。

现在我决定我需要再添加 1 个过滤器,总共有 5 个过滤器。这将成倍增加“if”语句的数量,我想知道是否有更好的方法来实现这一点?

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

非常感谢任何帮助!

4

3 回答 3

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 = ?
    

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

不过,对于 MySQLi 的参数化,我可能有点糊涂。我是PDO的人。

于 2013-09-23T20:00:17.900 回答
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))..)

于 2013-09-23T19:38:00.670 回答
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、发送以供您查看,并迭代过滤的用户。

完毕!

于 2013-09-23T20:38:47.043 回答