PDO变量未正确绑定


PDO variables not binding properly

我有点困惑,因为我把所有东西都正确地放在一起了,而且我已经在这里呆了几个小时了。我不断收到此错误

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

这是我收集信息的客户端代码段:

    $('#card-filter-form').submit(function(e){
            e.preventDefault();
            var contents = {
                card_name : $('#card_name').val(),
                card_number : $('#card_number').val(),
                setlist__id : $('#setlist__id').val(),
                ygo_rarity__id : $('#ygo_rarity__id').val(),
                ygo_card_type__id : $('#ygo_card_type__id').val(),
                ygo_attribute__id : $('#ygo_attribute__id').val(),
                ygo_monster_type__id : $('#ygo_monster_type__id').val(),
                level : $('#level').val(),
                atk : $('#atk').val(),
                def : $('#def').val()
            };
            var spinner = new Spinner().spin();
            var target = document.getElementById('card-search-filter-reset');
            target.appendChild(spinner.el);
            $.ajax({
                url : '../assets/server/cardSearch.php',
                type : 'POST',
                data : contents,
                dataType : 'JSON',
                success : function(data){
                    spinner.stop();
                    if(!data.errors){
                        $('#results-table').html(data.table);
                    }else{
                        alert(data.message);
                    }
                },
                error: function (request, status, error) {
                    spinner.stop();
                       console.log(request.responseText);
                }
            });
        });

这是我的服务器端代码片段:

$card_name = $_REQUEST['card_name'];
$card_number = $_REQUEST['card_number'];
$setlist__id = $_REQUEST['setlist__id'];
$ygo_rarity__id = $_REQUEST['ygo_rarity__id'];
$ygo_card_type__id = $_REQUEST['ygo_card_type__id'];
$ygo_attribute__id = $_REQUEST['ygo_attribute__id'];
$ygo_monster_type__id = $_REQUEST['ygo_monster_type__id'];
$level = $_REQUEST['level'];
$atk = $_REQUEST['atk'];
$def = $_REQUEST['def'];

$where = "1=1";
$where .= empty($card_name) ? "" : " AND c.card_name LIKE :card_name";
$where .= empty($card_number) ? "" : " AND card_number LIKE :card_number";
$where .= empty($setlist__id) ? "" : " AND c.setlist__id = :setlist__id";
$where .= empty($ygo_rarity__id) ? "" : " AND c.ygo_rarity__id = :ygo_rarity__id";
$where .= empty($ygo_card_type__id) ? "" : " AND c.ygo_card_type__id = :ygo_card_type__id";
$where .= empty($ygo_attribute__id) ? "" : " AND c.ygo_attribute__id = :ygo_attribute__id";
$where .= empty($ygo_monster_type__id) ? "" : " AND c.ygo_monster_type__id = :ygo_monster_type__id";
$where .= empty($level) ? "" : " AND c.level = :level";
$where .= empty($atk) ? "" : " AND c.atk = :atk";
$where .= empty($def) ? "" : " AND c.def = :def";
$q = "SELECT c.id, CONCAT_WS('-', s.set_abbr, c.card_number) as card_number, c.card_name, c.ygo_rarity__id, a.card_attribute, ct.card_type, m.type, c.level, c.atk, c.def FROM priceguide.cardlist c
    INNER JOIN priceguide.setlist s
    ON c.setlist__id = s.id
    LEFT JOIN priceguide.ygo_attribute a
    ON c.ygo_attribute__id = a.id
    LEFT JOIN priceguide.ygo_card_type ct
    ON c.ygo_card_type__id = ct.id
    LEFT JOIN priceguide.ygo_monster_type m
    ON c.ygo_monster_type__id = m.id
    WHERE $where
    ORDER BY card_number ASC";
$stmt = $CONN->prepare($q);
$card_name = "%".$card_name."%";
$card_number = "%".$card_number."%";
if(!empty($card_name)) $stmt->bindValue(":card_name", $card_name, PDO::PARAM_STR);
if(!empty($card_number)) $stmt->bindValue(":card_number", $card_number, PDO::PARAM_STR);
if(!empty($setlist__id)) $stmt->bindValue(":setlist__id", $setlist__id, PDO::PARAM_INT);
if(!empty($ygo_rarity__id)) $stmt->bindValue(":ygo_rarity__id", $ygo_rarity__id, PDO::PARAM_INT);
if(!empty($ygo_card_type__id)) $stmt->bindValue(":ygo_card_type__id", $ygo_card_type__id, PDO::PARAM_INT);
if(!empty($ygo_attribute__id)) $stmt->bindValue(":ygo_attribute__id", $ygo_attribute__id, PDO::PARAM_INT);
if(!empty($ygo_monster_type__id)) $stmt->bindValue(":ygo_monster_type__id", $ygo_monster_type__id, PDO::PARAM_INT);
if(!empty($level)) $stmt->bindValue(":level", $level, PDO::PARAM_INT);
if(!empty($atk)) $stmt->bindValue(":atk", $atk, PDO::PARAM_INT);
if(!empty($def)) $stmt->bindValue(":def", $def, PDO::PARAM_INT);

$stmt->execute();

我很确定我已经用细齿梳子检查了几次所有内容,一切似乎都是正确的。不过,对于 if 语句来说,这应该无关紧要,因为如果未设置变量,则不会存在任何参数供其附加到。所以我对这整件事感到困惑。为什么它告诉我我的参数不正确,而事实并非如此?

更新:根据要求,我添加了javascript代码以显示我的数据来自何处。

我的猜测是

$card_name = "%".$card_name."%";
$card_number = "%".$card_number."%";
if(!empty($card_name)) $stmt->bindValue(":card_name", $card_name, PDO::PARAM_STR);
if(!empty($card_number)) $stmt->bindValue(":card_number", $card_number, PDO::PARAM_STR);

导致问题 - 此时$card_name$card_number永远不会为空,即使它们在您创建$where时为空,因此您将有太多绑定变量。