PDO multi-Filter sql query

前端 未结 2 1364
终归单人心
终归单人心 2021-01-22 08:14

Is there a simpler way for me to code this and perform the same thing without having to have so many queries? Im trying to add pagination (not included in code here) and it work

相关标签:
2条回答
  • 2021-01-22 08:45

    And My Second thought:

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

    It needs testing and as truth said you might not need the OR but that is upto exactly how your form and filtering works tbh, but I am gonna leave it at that it should give you pointers to move to the next stage.

    Edit again:

    Couldn't help myself, here is a third possibility:

    $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 讨论(0)
  • 2021-01-22 08:45

    My thought is to iterate the $_POST array and bind only the variables you need.

    You are misunderstanding the use of AND and OR. If only one of the two is selected, you don't need to OR on the second one!

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

    The code will not work for you as is, so don't copy/paste it right away.

    This function assumes that the form names match the database names, and will act accordingly. If your column name is module_type, name the form field which matches it module_type as well.

    The advantages of such code, is that you can add more columns and more filters, and you won't have to change a single line of code :)

    0 讨论(0)
提交回复
热议问题