Php MySQL PDO Name Value Prepared语句仅使用最后一个参数
如标题所示,我使用MySQL PDO和一个准备好的语句,执行时,我得到一个值(最后提供的值)推送到所有字段中 表如下所示:Php MySQL PDO Name Value Prepared语句仅使用最后一个参数,php,pdo,mysqli,Php,Pdo,Mysqli,如标题所示,我使用MySQL PDO和一个准备好的语句,执行时,我得到一个值(最后提供的值)推送到所有字段中 表如下所示: id(整数-自动递增) a_id(int) b_id(int) INSERT如下所示: INSERT INTO my_table(a_id, b_id) VALUES (:a_id, :b_id) 要插入的代码如下所示 $stmt = $conn->prepare($sql); foreach($params as $k => $v) { $s
- id(整数-自动递增)
- a_id(int)
- b_id(int)
INSERT INTO my_table(a_id, b_id)
VALUES (:a_id, :b_id)
要插入的代码如下所示
$stmt = $conn->prepare($sql);
foreach($params as $k => $v) {
$stmt->bindParam(
$k,
$v
);
}
$stmt->execute();
语句成功插入一个值(确认$conn存在、处于活动状态和打开状态,语句已设置并绑定参数)
我已经通过在foreach内部调试确认了这些值,在这里我得到了两个参数(以$params为单位):a_id=>1,:b_id=>9999
不过我的记录是({new_id},9999,9999)。
这意味着它会看到并使用“:b_id”=>9999,但似乎会删除或覆盖“:a_id”=>1
我认为下划线可能是一个问题(但显然有几个人在过去审查了源代码,表明下划线是好的…尽管连字符不是)
我没有重用参数(我的理解是每个准备好的语句允许使用一个参数)
这里有我遗漏的命名参数问题吗?由于基本上是->bindParam()to->execute(),所以没有太多的空间让我进行故障排除
我试图在使用无脂肪框架时解决基于ORM的数据访问的速度问题,但我不认为存在干扰
作为参考,这是在PHP5.5.8/Windows/IIS下运行的
编辑:
我可以确认,移动到位置参数也在做同样的事情
INSERT INTO my_table(a_id, b_id)
VALUES (?, ?)
代码更改为
$stmt = $conn->prepare($sql);
$i = 1;
foreach($params as $value) {
$stmt->bindParam(
$i,
$value
);
$i++;
}
$stmt->execute();
要澄清$params数组是如何设置的。。。这段代码(这是抽象数据库处理程序的核心)正在被传递,数组是手动构造的
i、 e
仍然得到({new_id},9999,9999)
注意:为了消除混淆,除了使用基于位置的传球外,我还硬编码了值,以查看得到的结果
$results = \XX\DB::do_cmd(
$db,
self::SQL_INSERT,
array(
1,
1234,
)
);
我的记录出来了({new_id},12341234)。同样的问题,不同的价值观
我觉得这里有一个“抓住你了”的感觉。。。但我不知道那是什么
有趣的是,在插入之前,我根据这两个值(防止重复)对表中的现有记录进行了双重检查,该检查正确地标识了该记录在那里。。。尽管数据库中有错误。。。这意味着SELECT和INSERT对参数的处理是相同的(尽管这并不奇怪,因为参数处理是相同的)
编辑2:
更新为已解决的注释。使用
$stmt->execute($params); // scrap the foreach nonsense...
$stmt->execute($params); // scrap the foreach nonsense...
bindValue()而不是bindParam()也是合适的
注意:我使用的是以下PHP文档(),它没有区分bindValue()和bindParam()…变量必须通过引用调用:
$stmt = $conn->prepare($sql);
foreach($params as $k => &$v) {
$stmt->bindParam(
$k,
$v
);
}
$stmt->execute();
请参见此处的第一条用户评论:
谢谢大家的帮助 我同意Michael的解决方案,但也测试了Ryan的 i、 e 更新为已解决的注释。使用
$stmt->execute($params); // scrap the foreach nonsense...
$stmt->execute($params); // scrap the foreach nonsense...
bindValue()而不是bindParam()也是合适的
总而言之,根据Ryan的评论,我正在推出一个答案
再次感谢 您可以发布设置
$params
的代码和定义$sql
的代码吗?如果PDO正在模拟prepares(ATTR\u EMULATE\u prepares
),则可以重用参数,这是MySQL的默认设置。此外,请发布var\u dump($params)
,尽管您已经调试过它。您可以简化此操作以避免bindParam()
,因为您没有指定类型。您可以只使用$stmt->execute($params)
在“foreach”循环中使用“bindValue”而不是“bindParam”。否则,您只绑定到只有一个变量的变量“$v”!它的最后一个值是“9999”。@RyanVincent发现得很好。我可以确认RyanVincent和@MichaelBerkowski工作中提到的两个选项(即直接在$params上执行,并使用bindValue而不是BindParam)。谢谢我不知道如何在这里标记答案,但我很确定有人必须在评论之外发布一个答案…那是行不通的。。。它将与每个参数一起执行。。。如果我在做多个插入,我可能会在循环中执行->execute()。。。事实证明,这个循环在这种情况下是不必要的。对不起,我第一次看错了这个问题,就下结论了。我重新阅读并完全更改了我的答案。这与最初提出的答案不同,但你是对的,()确实引起了对通过引用传递的变量的注意;然而,我不应该强制执行,我不确定这在foreach中会起什么作用。我只知道&不能进入函数调用(5.3.0生成警告,5.4.0生成致命错误等):您确实看到&进入了循环的foreach部分,而不是函数调用,对吗?基本上,我的答案和Ryan的答案是一样的——他指出你将它绑定到单个变量$v,我正在解释如何克服这个问题。谢谢Peter!我明白你现在的目的。我想我已经看到它更普遍地通过“虚拟”变量来表达。。。(即my_func($k,$dummy=$v);键入thing…)特别是在实际的函数调用中,但是您正在获取对变量的引用,而不是本例中的变量,以纠正绑定问题。如果我还是很笨,你愿意继续,请放心,但我认为我们基本上都被涵盖了。谢谢你为我们发布了答案,我们都很乐意提供帮助。