PDO 使用 foreach 绑定 n 次相同的值
Posted
技术标签:
【中文标题】PDO 使用 foreach 绑定 n 次相同的值【英文标题】:PDO binds n times same value with foreach 【发布时间】:2013-08-18 17:45:56 【问题描述】:我在 php 中有函数,它应该在 mysql IN 语句中绑定这么多变量,即在数组中。 我的问题是变量和键正在改变,但函数只绑定最后一个值 n 次。
我不知道问题出在哪里......
这是我的类方法:
public function getOtListByOtNumbers($conditions)
$data_array = $conditions[SEARCH_OT];
# To find last key (remove coma)
$quantity = count($data_array);
$marks = '';
# Bind name string && rewriting value as integer
foreach ($data_array as $key => $value)
$i = $key+1;
if ($i == $quantity)
$marks .= ':key'.$i;
else
$marks .= ':key'.$i.', ';
# Query
$sql="
SELECT
c_int_id,
c_ot,
c_tickets_amount,
c_basket_value,
c_person,
c_company,
c_city,
c_package_number,
c_delivery_method,
c_ot_date,
c_email,
c_phone,
c_comment,
c_send
FROM ws_orders
WHERE c_ot IN (".$marks.")
ORDER BY c_int_id DESC
LIMIT :first, :last ";
$stmt = $this->PDO->prepare($sql);
# Bind n values
// Here is a problem
var_dump($data_array); // var dump 1
foreach ($data_array as $key => $param)
$key_number = $key +1;
$key_name = 'key'.$key_number;
$stmt->bindParam($key_name, $param, PDO::PARAM_INT);
var_dump($key_name); // var dump 2
var_dump($param); // var dump 3
# Bind limit values
$stmt->bindParam('first', $conditions[OT_SEARCH_FIRST_ROW], PDO::PARAM_INT);
$stmt->bindParam('last', $conditions[OT_SEARCH_ROW_LIMIT], PDO::PARAM_INT);
# If executed return result
if ($stmt->execute() != FALSE)
$stmt_result = $stmt->fetchAll();
$stmt->closeCursor();
var_dump($stmt_result); // var dump 4
# If not executed print debug and return FALSE
else
var_dump($stmt->errorInfo());
$this->debugQuery($stmt);
$stmt_result = FALSE;
return $stmt_result;
这里是 var dupms:
var 转储 1
array (size=2)
0 => string '2761531'
1 => string '2760650'
var 转储 2 & 3
string 'key1' (length=4)
string '2761531'
string 'key2' (length=4)
string '2760650'
来自该执行的 SQL 查询
SELECT
c_int_id,
c_ot,
c_tickets_amount,
c_basket_value,
c_person,
c_company,
c_city,
c_package_number,
c_delivery_method,
c_ot_date,
c_email,
c_phone,
c_comment,
c_send
FROM ws_orders
WHERE c_ot IN ('2760650', '2760650')
ORDER BY c_int_id DESC
LIMIT 0, 30
那么我做错了什么?
编辑
所以我做到了;) 问题出在 foreach 上
代替:
foreach ($data_array as $key => $param)
$key_number = $key +1;
$key_name = 'key'.$key_number;
$stmt->bindParam($key_name, $param, PDO::PARAM_INT);
var_dump($key_name); // var dump 2
var_dump($param); // var dump 3
我给:
for ($key_number = 0; $key_number < $quantity + 1; $key_number++)
$key_name = 'key'.$key_number;
$stmt->bindParam($key_name, $data_array[$key_number], PDO::PARAM_INT);
它有效,但我仍然不知道早期的 foreach 有什么问题......
【问题讨论】:
太好了,你让它工作了!你应该回答这个问题并自己接受。这是“关闭”问题的推荐方式。 我的代表少于 10 个,所以我不能在 8 小时之前完成 :) 也许有人会描述为什么 foreach 不起作用 帮了一点忙 :-) 不知道foreach
——当我看到这个问题时,我想,$conditions
一定有一些东西,也许它不完全包含有什么预期的。不过,现在没有时间 - sry
$conditions
是多维数组,但我只使用了一个子数组,该数组的内容列在 var dump 1 中。每个循环中的数据都在变化(var dump 2 & 3 列表),但 bindParam 看不到它
【参考方案1】:
PDO::bindParam()
和 PDO::bindValue()
之间存在区别。 PDO::bindParam
绑定参考,而不是值。当 foreach 进程结束时,$param
将引用最后一个数组值。在execute
调用时,所有绑定的引用都将被评估为相同的值。
官方PDO::bindParam
文档说:
与 PDOStatement::bindValue() 不同,变量被绑定为引用 并且只会在 PDOStatement::execute() 被评估时 调用。
如果您想在foreach
中绑定值,请使用PDO::bindValue
。
【讨论】:
【参考方案2】:如果您将变量作为引用传递,它将对值起作用,但对键不起作用。
示例:
foreach ($data_array as $key => &$param)
$key_number = $key + 1; //this won't work
$key_name = 'key' . $key_number;
$stmt->bindParam($key_name, $param, PDO::PARAM_INT);
var_dump($key_name); // var dump 2
var_dump($param); // var dump 3
【讨论】:
【参考方案3】:问题在于 BindParam 通过引用传递第二个值。 PHP 重用(或在这种情况下似乎)$param 的地址,而不是实际值。 您的 foreach 可以使用:
$stmt->bindParam($key, $data_array[$key]);
这具有将数组的地址位置绑定在那个关键位置的效果,所以当你的sql执行时,它会得到正确的值。
你可能想要:
$stmt->bindValue($key, $param);
应该在 foreach 循环中而不是在执行语句中求值,并且是传递的值而不是地址位置。
【讨论】:
以上是关于PDO 使用 foreach 绑定 n 次相同的值的主要内容,如果未能解决你的问题,请参考以下文章
使用 foreach 获取时覆盖 PDO 的 fetch()