2012-07-31 82 views
2

有没有更简单的方法让我编码并执行相同的事情,而不必有太多的查询?我试图添加分页(这里没有包含在代码中),它适用于我的ALL查询,但AND/OR查询给出了有趣的结果,并且正在变得令人头疼。除此之外,对结果进行筛选仅仅需要分页。PDO多过滤器sql查询

$filter = isset($_POST['filter']) ? $_POST['filter'] : null; 
$status = isset($_POST['status']) ? $_POST['status'] : null; 

if(empty($filter) && empty($status)) { 

    //echo 'ALL query'; 
    $sql = 'SELECT * FROM _product JOIN _module_type ON module_type = module_id'; 
    $sth = $link->prepare($sql); 
    $sth->execute(array()); 
    $result = $sth->fetchall(); 

} else { 
    // display result if filter AND status are selected 
    if(!empty($filter) && !empty($status)) { 

     //echo 'AND query'; 
     $sql = 'SELECT * FROM _product JOIN _module_type ON module_type = module_id WHERE module_type = :filter AND product_status = :status'; 
     $sth = $link->prepare($sql); 
     $sth->execute(array(':filter' => $filter, ':status' => $status)); 
     $result = $sth->fetchall(); 

    } else { 
     // display result if filter OR status are selected 
     if(!empty($filter) || !empty($status)) { 

      //echo 'OR query'; 
      $sql = 'SELECT * FROM _product JOIN _module_type ON module_type = module_id WHERE module_type = :filter OR product_status = :status'; 
      $sth = $link->prepare($sql); 
      $sth->execute(array(':filter' => $filter, ':status' => $status)); 
      $result = $sth->fetchall(); 

     } 
    } 
} 

//test sql 
echo $sql.'<br />'; 

$bgcolor = ''; 
foreach($result as $key => $value) { 

    if(($bgcolor=='#ffffff') ? $bgcolor='#f1f1f1' : $bgcolor='#ffffff') { 

    echo '<tr bgcolor="'.$bgcolor.'">'; 
    echo '<td>'.$value['product_id'].'</td>'; 
    echo '<td>'.$value['product_name'].'</td>'; 
    echo '<td>'.$value['product_type'].'</td>'; 
    echo '<td>'.$value['module_name'].'</td>'; 
    echo '<td>'.$value['product_price'].'</td>'; 
    echo '<td>'.$value['product_status'].'</td>'; 
    echo '</tr>'; 
    } 
} 
    echo '</table>'; 
+1

一行今天早上我也有类似的问题。在这里看到答案:http://stackoverflow.com/questions/11740066/simplify-a-mysql-query-that-c​​an-have-multiple-input-options-using-php – Jim 2012-07-31 19:46:02

回答

2

我的第二个想法:

$sql = 'SELECT * FROM _product JOIN _module_type ON module_type = module_id WHERE'; 
if(!empty($filter) || !empty($status)){ 
    $sql .= ' module_type = :filter '.(!empty($filter) && !empty($status) ? 'AND' : 'OR').' product_status = :status'; 
    $sth = $link->prepare($sql); 
    $sth->bindValue(':filter', $filter); 
    $sth->bindValue(':status', $status); 
}else{ $sth = $link->prepare($sql); } 
$result = $sth->execute(); 

它需要进行测试和真理说你可能不需要的或但那是高达表单和过滤是如何工作的TBH,但我不会离开它应该让你指向下一个阶段。再次

编辑:

控制不住自己,这里是第三种可能性:

$params = array(); 
$where = array(); 

if(!empty($filter)){ 
    $params[':filter'] = $filter; 
    $where[] = 'module_type = :filter'; 
} 
if(!empty($status)){ 
    $params[':status'] = $status; 
    $where[] = 'product_status = :status'; 
} 

$sql = 'SELECT * FROM _product JOIN _module_type ON module_type = module_id'.(sizeof($where) > 0 ? ' WHERE '.implode(' AND ', $where) : ''); 

$sth = $link->prepare($sql); 
foreach($params as $k=>$v) $sth->bindValue($k, $v); 
$result = $sth->execute(); 
+0

我试过你的第二个例子,我移动了“WHERE”在sql之前将字符串连接到module_type之前,以确保它在页面加载时显示所有结果。我也调整了其他的东西。现在很好,我现在要测试你的第三个例子。 – dynamo 2012-07-31 20:23:55

+0

@dynamo请确保采取我最新的编辑,原始文章有问题 – Sammaye 2012-07-31 20:27:02

1

我的想法是迭代$_POST阵列并绑定只有你所需要的变量。

您误解了AND和OR的使用。如果只选择其中一个,则不需要对第二个进行OR操作!

<?php 

    /** 
    * @param PDO $pdo  Database connection 
    * @param array $parameters Parameters (status, filter) 
    * 
    * @return array   The resultset returned from the query 
    */ 
    function select_product(\PDO $pdo, array $parameters = array()) { 
     $query = <<<MySQL 
SELECT * 
    FROM _product 
    JOIN _module_type 
    ON module_type = module_id 

MySQL; 
     if (!empty($parameters)) { 
      $query .= "WHERE "; 
      $where_clauses = array(); 
      foreach ($parameters as $param => $value) { 
       $where_clauses[] = "$param = :$param"; 
      } 
      $where_clauses = implode(" AND ", $where_clauses); 
      $query .= $where_clauses; 
     } 

     $stmt = $pdo->prepare($query); 
     foreach ($parameters as $param => $value) { 
      $stmt->bindValue(":$param", $value); 
     } 
     $stmt->execute(); 

     $results = $stmt->fetchAll(PDO::FETCH_ASSOC); 
     return $results; 
    } 

    try { 
     $db = new PDO("mysql:host=localhost;dbname=database_name", "user", "password"); 
     $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
     $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
     select_product($db, $_POST); 
    } 
    catch (PDOException $e) { 
     die("Database problem occurred! " . $e->getMessage()); 
    } 

的代码将你不工作原样,所以不要复制/粘贴的时候了。

该函数假定表单名称与数据库名称相匹配,并将相应地执行。如果您的列名称为module_type,请命名与之匹配的表格字段module_type

这种代码的优点是,你可以添加更多的列和更多的过滤器,你将不会有改变的代码:)