【问题标题】:Cannot use positional arguments after argument unpacking while preparing a statement在准备语句时参数解包后不能使用位置参数
【发布时间】:2020-11-10 14:30:17
【问题描述】:

我正在尝试将可变数量的值绑定到我准备好的语句的 IN () 条件中,并稍后在查询中绑定更多值,但出现错误:

PHP 致命错误:参数解包后无法使用位置参数。

我的代码如下:

$ccarr=explode(",", $cc);
$in = str_repeat('?,', count($ccarr) - 1) . '?';
$op_r=$tfvarr[2]; 
$budg_et=$tfvarr[1];
$budg_et1=$tfvarr111111;

$sqldesk="SELECT subsubcatid_parent, plink, deskid, sum(itprice) as totprice FROM desktop_items a, items_table b, obsubsubcat c where subsubcatid_parent IN ($in) and a.itno = b.itno and a.subsubcatid_parent=c.subsubcatid group by subsubcatid_parent, deskid having totprice > ? && totprice ? ?" ;

if($stmtdesk = $conn->prepare($sqldesk))
{
    $types = str_repeat('i', count($ccarr));
    $types .= 'isi';
    $stmtdesk->bind_param($types, ...$ccarr, $budg_et1, $op_r, $budg_et);
    $stmtdesk->execute();
    $stmtdesk->store_result();
    $stmtdesk->bind_result($subsubcatid_parentdesk, $plinkdesk, $deskiddesk, $totpricedesk);
}

如何绑定所有值而不出现解包错误?

【问题讨论】:

  • 请不要参与回滚战。我通过应用适当的格式并删除不相关的“请帮助”签字来改进您的问题。

标签: php mysqli prepared-statement bindparam argument-unpacking


【解决方案1】:

我建议您将附加值推送到您的 $ccarr 数组中,这样您只需将 $ccarr 插入到 bind_param() 中。

看起来$op_r 是一个“运算符”而不是一个值。所以这不应该被束缚。 Listen to Victor。运算符值应根据硬编码值的白名单进行验证,并直接注入到您的查询字符串中。

$ccarr = explode(",", $cc);
$in = str_repeat('?,', count($ccarr) - 1) . '?';
$op_r = $tfvarr[2]; 
$budg_et = $tfvarr[1];
$budg_et1 = $tfvarr111111;

array_push($ccarr, $budg_et1, $budg_et);
$types = str_repeat('i', count($ccarr));

$sqldesk = "SELECT subsubcatid_parent, plink, deskid, SUM(itprice) AS totprice
            FROM desktop_items a
            JOIN items_table   b ON a.itno = b.itno
            JOIN obsubsubcat   c ON a.subsubcatid_parent = c.subsubcatid
            WHERE subsubcatid_parent IN ($in)
            GROUP BY subsubcatid_parent, deskid
            HAVING totprice > ? AND totprice {$op_r} ?";

$stmtdesk = $conn->prepare($sqldesk);
$stmtdesk->bind_param($types, ...$ccarr);
$stmtdesk->execute();
$stmtdesk->store_result();
$stmtdesk->bind_result($subsubcatid_parentdesk, $plinkdesk, $deskiddesk, $totpricedesk);

此外,我不建议使用 old-skool comma-JOIN。显式声明 JOIN 更清晰、更现代,并且使用 ON 表达式来描述连接关系。

最后,MySQL 中的&& 应该是AND。在你的 sql 字符串中始终使用全大写来编写 MySQL 关键字。

【讨论】:

  • 感谢您的回复。我可以在一个数组中推送更多值,但这会产生问题。实际上,它都是动态的,数组中有不同数量的值(以及不同的数据类型)。所以基本上我想要 2 个数组,一个专门用于我使用 &in 的 IN() 运算符,另一个数组用于 SQL 查询的其余部分。 && 是 AND 运算符,但是 ??将在运行时取值。我希望你明白了。
  • 我只能回答您发布的问题。我不可能知道你的项目是怎么写的。我的回答非常慷慨;但我担心我偶然发现了一个“移动目标”的问题。我看不出有任何理由不能将任何附加参数合并到更早声明的数组中,因此您只需“传播”第一个数组变量。
  • stackoverflow.com/a/51036322/2943403 继续构建参数和类型。
  • 米克,非常感谢您在这个问题上的宝贵时间。您从字面上解决了我一直坚持的问题,并就良好的代码样式向我提供了建议(我实际上是一个老学生,并且在 12 年后从事 php+mysql 工作)。您包含在 {} 中的那个运算符部分并没有出现在我的脑海中。再次感谢!
猜你喜欢
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
  • 1970-01-01
  • 2022-11-11
  • 2017-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多