问题 PDO位置和命名参数作为同一准备查询的一部分?


我正在学习PDO的绳索。

这是我的sql(WHERE中可以出现的参数数量是变量)。

    SELECT
        ID, title

    FROM
        table

    WHERE
        something = ?

    ORDER BY 
        :sort :dir 

    LIMIT 
        :start, :results

这是我的代码:

        $query = $conn->prepare($sql);

        if ($parameters) {

            $i = 0;
            foreach ($parameters AS $parameter) {

                $i++;
                $query->bindParam($i, $parameter);

            }

        }

        $query->bindParam(':start', $pagination['start'], PDO::PARAM_INT);
        $query->bindParam(':results', $pagination['results'], PDO::PARAM_INT);
        $query->bindParam(':sort', $pagination['sort']);
        $query->bindParam(':dir', $pagination['dir']);

        $query->execute();

......以下是它生成的例外情况:

 Invalid parameter number: mixed named and positional parameters

是否无法在同一查询中组合位置参数和命名参数?或者我错过了什么?

谢谢!


5560
2018-06-24 09:14


起源

我不确定 LIMIT但是 ORDER BY 不接受参数,至少不在我使用的PHP版本中(5.2.9) - jeroen
MySQL不会接受 引用值 为了 LIMIT 和 ORDER BY 条款,这些占位符被替换时会发生的情况。这不是一个PHP问题...而且有点让你的问题没有实际意义。 - Charles


答案:


是的,这是不可能的。

PDO.prepare

您不能在同一SQL语句中同时使用命名和问号参数标记;选择一个或另一个参数样式。


10
2018-06-24 09:24



好的,谢谢你的信息。考虑到我有一个可变数量的参数,那么将变量绑定到ORDER BY和LIMIT子句是不可能的? (据我所知,你只能使用命名参数来执行此操作。但是命名参数不适合具有未知数量参数的情况。) - Travis
您无法绑定列名,因此无法绑定:sort和:dir。为所有参数指定名称。 - Naktibalda


使用包装函数,一个天真的替换函数就足够了。

if (strpos($sql, ":")) {
    $i = -1;
    while (strpos($sql, "?") && isset($parameters[++$i])) {
        $parameters[":p$i"] = $parameters[$i];
        unset($parameters[$i]);
        $sql = preg_replace("/[?]/", ":p$i", $sql, 1);
    }
}

将$ sort和$ dir直接混合到$ sql查询中。这两个是SQL标识符,而不是数据。


2
2018-06-24 12:49