根据这个example准备好的语句我首先绑定参数,然后设置参数的值。
我们假设我有一个2-dim数组$别名
Preferences
为什么这段代码正常工作
$array1 = [
'id' => 1,
'tstamp' => 123456789,
'alias' => '$alias',
];
$array2 = [
'id' => 1,
'tstamp' => 123456789,
'alias' => '$alias2',
];
$alias = [$array1, $array2];
这不是吗?
$insert = 'INSERT INTO abcdef VALUES (?,?,?)';
$insertStmt = $conn->prepare($insert);
foreach ($alias as $array) {
$insertStmt->bind_param('iis', $array['id'], $array['tstamp'], $array['alias']);
$insertStmt->execute();
}
如果我必须一直绑定参数,那么会有更多的交通,不是吗?
答案 0 :(得分:4)
bind_param()
通过引用绑定到特定的zval container。在循环的每次迭代中,都会为其新的数组符号表分配自己的zval容器。如果在绑定时zval容器不存在,则将创建它们。可以用以下代码显示:
$insertStmt = $conn->prepare('INSERT INTO abcdef VALUES (?,?,?)');
$insertStmt->bind_param('sss', $array['id'], $array['tstamp'], $array['alias']);
var_dump($array);
输出:
array (size=3)
'id' => null
'tstamp' => null
'alias' => null
即使我们没有在任何地方声明$array
,该绑定也会使用空值隐式创建它。绑定将继续指向该空数组。
当然,当我们开始迭代别名数组时,每次都会重新创建$array
。我们绑定了参数的旧数组符号表现在不见了。我们尚未将任何内容绑定到新数组。
要解决此问题,您只需将bind_param()
循环内的foreach
移动为:
$insertStmt = $conn->prepare('INSERT INTO abcdef VALUES (?,?,?)');
foreach ($alias as $array) {
// bind to the new zval containers every iteration
$insertStmt->bind_param('sss', $array['id'], $array['tstamp'], $array['alias']);
$insertStmt->execute();
}
答案 1 :(得分:4)
如果我必须始终绑定参数,那么还有更多 交通,不是吗?
流量是根据prepare
和execute
事件生成的。
话虽如此,您可以重新安排一点以将->bind_param()
移到循环外。更简单的方法是绑定变量而不是数组:
$array1 = ['id' => 1, 'tstamp' => 123456789, 'alias' => '$array1'];
$array2 = ['id' => 1, 'tstamp' => 123456789, 'alias' => '$array2'];
$arrays = [$array1, $array2];
$insert = 'INSERT INTO abcdef VALUES (?,?,?)';
$insertStmt = $conn->prepare($insert);
$bv_id = NULL;
$bv_tstamp = NULL;
$bv_alias = NULL;
$insertStmt->bind_param('iis', $bv_id, $bv_tstamp, $bv_alias);
foreach ($arrays as $array) {
// you could use extract($array, ...) below
// but its use is highly discouraged
$bv_id = $array['id'];
$bv_tstamp = $array['tstamp'];
$bv_alias = $array['alias'];
$insertStmt->execute();
}
如果必须使用数组,请使用以下方法:
$array = ['id' => null, 'tstamp' => null, 'alias' => null];
$insertStmt->bind_param('iis', $array['id'], $array['tstamp'], $array['alias']);
foreach ($arrays as $copy) {
foreach ($copy as $k => $v) {
$array[$k] = $v;
}
$insertStmt->execute();
}
请注意,我在foreach
构造中为循环变量使用了不同的名称(我们需要跟踪绑定到该语句的数组,并且循环变量在每次迭代时都会被覆盖)。您将必须手动将值从循环变量复制到绑定数组。
答案 2 :(得分:-1)
以您的情况
此代码有效
$insert = 'INSERT INTO abcdef VALUES (?,?,?)';
$insertStmt = $conn->prepare($insert);
foreach ($alias as $array) {
$insertStmt->bind_param('iis', $array['id'], $array['tstamp'], $array['alias']);
$insertStmt->execute();
}
由于数组迭代,我们使用for循环或foreach提取键数组中的键值,因此在$ array变量中的此代码值将从$ alias数组中设置一个值
在此代码中
$insert = 'INSERT INTO abcdef VALUES (?,?,?)';
$insertStmt = $conn->prepare($insert);
$insertStmt->bind_param('iis', $array['id'], $array['tstamp'], $array['alias']);
foreach ($alias as $array) {
$insertStmt->execute();
}
您使用了$ array变量,该变量未在任何上限区域中初始化或声明,因此它将获得空值,因此每次execute函数将获得空值。...