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は必要ないかもしれませんが、それはフォームとフィルタリングがtbhでどのように機能するかによって異なりますが、次の段階に進むためのポインターが得られるはずです。

もう一度編集します。

自分自身を助けることができませんでした、ここに3番目の可能性があります:

$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の使用を誤解しています。2つのうち1つだけが選択されている場合は、2番目の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ます。

このようなコードの利点は、列とフィルターを追加できることと、コードの1行を変更する必要がないことです:)

于 2012-07-31T19:56:30.947 に答える