0

私は 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%
)

質問: バグはどこにありますか? ありがとう!

4

1 に答える 1

3

残念ながら、「私のコードを見て、どこにバグがあるのか​​教えてください」のような質問は、このサイトでは話題から外れています。

可能な唯一の答えは、クエリをデバッグする方法と問題を特定する方法を教えることです。

ほら、クエリとパラメーターがあります。

生の PDO で実行してみてください。それは機能しますか?
そうでない場合は、条件を(対応するパラメーターとともに)1つずつ取り出してみてください。どっちで止まった?これで問題を再現できますか?

できるだけ問題を絞り込むようにしてください。とにかくそれが唯一の方法です。

于 2013-09-04T10:19:05.500 に答える