2

有没有一种更简单的方法可以让我编写代码并执行相同的操作而无需进行这么多查询?我正在尝试添加分页(此处未包含在代码中),它适用于我的 ALL 查询,但 AND / OR 查询给出了有趣的结果,并且变得令人头疼。除此之外,结果的过滤效果很好,只需要分页。

$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>';
4

2 回答 2

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();

它需要测试,正如事实所说,您可能不需要 OR,但这取决于您的表单和过滤的工作方式,但我将把它留在那里,它应该为您提供进入下一阶段的指示。

再次编辑:

忍不住,这是第三种可能性:

$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();
于 2012-07-31T19:51:43.347 回答
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

此类代码的优点是您可以添加更多列和更多过滤器,并且您不必更改一行代码:)

于 2012-07-31T19:56:30.947 回答