具有已准备语句的PDO动态查询


PDO dynamic queries with prepared statement

我有一个PDO类包装器:

class DB {
        private $dbh;
        private $stmt;
        private $queryCounter = 0;
        public function __construct($user, $pass, $dbname) {
            $dsn = 'mysql:host=localhost;dbname=' . $dbname;
            $options = array(
                PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
                PDO::ATTR_PERSISTENT => true
            );
            try {
                $this->dbh = new PDO($dsn, $user, $pass, $options);
            }
            catch (PDOException $e) {
                echo $e->getMessage();
                die();
            }
        }
        public function query($query) {
            $this->stmt = $this->dbh->prepare($query);
            return $this;
        }
        public function bind($pos, $value, $type = null) {
            if( is_null($type) ) {
                switch( true ) {
                    case is_int($value):
                        $type = PDO::PARAM_INT;
                        break;
                    case is_bool($value):
                        $type = PDO::PARAM_BOOL;
                        break;
                    case is_null($value):
                        $type = PDO::PARAM_NULL;
                        break;
                    default:
                        $type = PDO::PARAM_STR;
                }
            }
             $this->stmt->bindValue($pos, $value, $type);
             return $this;
        }
        public function execute($vars = array()) {
                $this->queryCounter++;
                if (isset($vars) && count($vars)) {
                    foreach ($vars as $k => $v ) {
                        $this->bind(($k+1), $v);
                    }
                }
                return $this->stmt->execute();
        }
        public function resultset($vars = array()) {
            $this->execute($vars);
            return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
        }
        public function single($vars = array()) {
            $this->execute($vars);
            return $this->stmt->fetch();
        }
    }

我的动态查询在这里:

        $per_page           = ($filter["show_by"] >= 25 && $filter["show_by"] <= 100) ? intval($filter["show_by"]) : 25; 
        $start          = intval($filter["page_id"]) ?  ($filter["page_id"] -1)*$per_page : 0;
        $sql_counter    = 'SELECT COUNT(*) count FROM `products` WHERE 1=1';
        $sql_result = 'SELECT * FROM `products` WHERE 1=1';
        $data = [];
        if (isset($filter["mode"]) != 'extra') {
            $sql_counter    .= ' AND `status` = :status';
            $sql_result     .= ' AND `status` = :status';
            $data[":status"] = 1;
        }
        if (intval($filter["category_id"])) {
            $sql_counter    .= ' AND FIND_IN_SET(:category_id, `cid`)';
            $sql_result     .= ' AND FIND_IN_SET(:category_id, `cid`)';
            $data[":category_id"] = $filter["category_id"];
        }       
        if (strlen($filter["search_by"]) > 0) {
            $search          = '%'.filter_var($filter["search_by"], FILTER_SANITIZE_STRING).'%';
            $sql_counter    .= ' AND `name` LIKE :search';
            $sql_result     .= ' AND `name` LIKE :search';
            $data[":search"] = $search;
        }   
        /*print_r($sql_counter);
        print_r($data);
        die();
        */
        $count  = $this->db->query($sql_counter)->single($data)[0];

但这给我返回了一个错误:

 PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

我的调试信息如下:

SELECT COUNT(*) count FROM `products` WHERE 1=1 AND `status` = :status AND FIND_IN_SET(:category_id, `cid`) AND `name` LIKE :search
Array
(
    [:status] => 1
    [:category_id] => 7
    [:search] => %123%
)

问题:bug在哪里?谢谢

不幸的是,像"请查看我的代码并告诉我哪里有bug"这样的问题在这个网站上肯定是离题的。

唯一可能的答案是告诉您如何调试查询以及如何本地化问题。

看,您有一个查询和参数。

试着用原始PDO运行它。它有效吗
如果没有,试着逐一列出你的条件(以及相应的参数)。它停在哪一个?你能用这个重现问题吗?

尽量缩小你的问题范围。这是唯一的办法。