遍历绑定参数中的数组 - 准备好的语句
Loop through array in bind parameters - prepared statement
我正在编写一个函数,我可以在其中执行一些数据库操作,在本例中是基于简单数组的插入数据
"insert" => array (
"1" => array (
"tnt_role" => array (
"rolename" => array (
"value" => "administrator",
"notation" => "string"
)
)
),
"2" => array (
"tnt_role" => array (
"rolename" => array (
"value" => "user",
"notation" => "string"
)
)
),
"3" => array (
"tnt_users" => array (
"username" => array (
"value" => "administrator",
"notation" => "string"
),
"userpassword" => array (
"value" => md5('admin', FALSE),
"notation" => "string"
),
"email" => array (
"value" => "someone@something.com",
"notation" => "string"
),
"roleid" => array (
"value" => "1",
"notation" => "int"
)
)
)
)
这里是函数的具体部分
case "insert":
foreach ($tables as $instance => $inserttables) {
foreach ($inserttables as $table => $fields) {
// create a count on the number of fields that are being parsed
$countfields = count($fields);
$sql = "INSERT INTO ". $table ." (" ;
$i = 0;
// set up the columns for the insert statement
foreach ($fields as $field => $value) {
$i++;
$sql .= $field;
if ($countfields != $i ) {
$sql .= ", ";
}
}
// close the column statement, open the value statement, since this is prepared, we will add question marks and add later the values
$sql .= ") ";
$sql .= "VALUES (";
$i = 0;
$parameters = "";
$notation = "";
foreach ($fields as $field => $value) {
$i++;
$sql .= "?";
// set up the notation in the bind parameters
switch($value['notation']) {
case "int":
$notation .= "i";
break;
case "string":
$notation .= "s" ;
break;
}
// need to escape the email and username values
$parameters .= "'".$value['value']."'" ;
if ($countfields != $i ) {
$sql .= ", ";
$parameters .= ", ";
}
}
$sql .= ")";
$stmt = mysqli_prepare($con, $sql);
mysqli_stmt_bind_param($stmt, $notation, $parameters);
if(mysqli_stmt_execute($stmt)) {
echo "data entered";
} else {
echo "error in following query:". $sql;
}
}
}
break;
这一切都很好,除了 1 个小问题,那就是当我在数据库中输入超过 1 个项目时。它给了我以下错误
mysqli_stmt_bind_param(): Number of elements in type definition string
doesn't match number of bind variables in .... line 647
过了一会儿我意识到是参数变量。这里的绑定参数只有 1 个变量,我用逗号将它们很好地分开(为了模仿列表)。查看此光学文件会说这看起来不错,但我认为绑定参数语句确实需要单独的变量。此时它实际上只看到一个变量,而不是我的测试用例中的 4 个。
我试过这样循环:
mysqli_stmt_bind_param($stmt, $notation,
foreach ($fields as $field => $value) {
echo $value['value'];
if ($countfields != $i ) {
echo ",";
}
}
);
但是没有用,因为它会吐出以下内容。
Parse error: syntax error, unexpected 'foreach' (T_FOREACH) in
有人知道如何解决这个问题吗?
==编辑==
table 结构符合要求,虽然我怀疑是那个问题,因为我得到一个绑定参数错误,而不是执行语句时的错误。
== 编辑 2 ==
还尝试了以下方法,但没有帮助,因为它没有堆叠(我在 PDO 中看到了这个)
foreach ($fields as $field => $value) {
switch($value['notation']) {
case "int":
$notation = "i";
break;
case "string":
$notation = "s" ;
break;
}
mysqli_stmt_bind_param($stmt, $notation, $value['value']);
}
您需要将每个变量单独传递给 mysqli_stmt_bind_param
,因此 $parameters
需要是一个数组,而不是字符串。更改以下代码行:
$parameters = "";
至:
$parameters = array();
和
$parameters .= "'".$value['value']."'" ;
至:
$parameters[] = $value['value'];
(请注意,使用准备语句时无需转义值)
删除这一行:
$parameters .= ", ";
最后,改变
mysqli_stmt_bind_param($stmt, $notation, $parameters);
至:
mysqli_stmt_bind_param($stmt, $notation, ...$parameters);
它应该可以正常工作。
我正在编写一个函数,我可以在其中执行一些数据库操作,在本例中是基于简单数组的插入数据
"insert" => array (
"1" => array (
"tnt_role" => array (
"rolename" => array (
"value" => "administrator",
"notation" => "string"
)
)
),
"2" => array (
"tnt_role" => array (
"rolename" => array (
"value" => "user",
"notation" => "string"
)
)
),
"3" => array (
"tnt_users" => array (
"username" => array (
"value" => "administrator",
"notation" => "string"
),
"userpassword" => array (
"value" => md5('admin', FALSE),
"notation" => "string"
),
"email" => array (
"value" => "someone@something.com",
"notation" => "string"
),
"roleid" => array (
"value" => "1",
"notation" => "int"
)
)
)
)
这里是函数的具体部分
case "insert":
foreach ($tables as $instance => $inserttables) {
foreach ($inserttables as $table => $fields) {
// create a count on the number of fields that are being parsed
$countfields = count($fields);
$sql = "INSERT INTO ". $table ." (" ;
$i = 0;
// set up the columns for the insert statement
foreach ($fields as $field => $value) {
$i++;
$sql .= $field;
if ($countfields != $i ) {
$sql .= ", ";
}
}
// close the column statement, open the value statement, since this is prepared, we will add question marks and add later the values
$sql .= ") ";
$sql .= "VALUES (";
$i = 0;
$parameters = "";
$notation = "";
foreach ($fields as $field => $value) {
$i++;
$sql .= "?";
// set up the notation in the bind parameters
switch($value['notation']) {
case "int":
$notation .= "i";
break;
case "string":
$notation .= "s" ;
break;
}
// need to escape the email and username values
$parameters .= "'".$value['value']."'" ;
if ($countfields != $i ) {
$sql .= ", ";
$parameters .= ", ";
}
}
$sql .= ")";
$stmt = mysqli_prepare($con, $sql);
mysqli_stmt_bind_param($stmt, $notation, $parameters);
if(mysqli_stmt_execute($stmt)) {
echo "data entered";
} else {
echo "error in following query:". $sql;
}
}
}
break;
这一切都很好,除了 1 个小问题,那就是当我在数据库中输入超过 1 个项目时。它给了我以下错误
mysqli_stmt_bind_param(): Number of elements in type definition string doesn't match number of bind variables in .... line 647
过了一会儿我意识到是参数变量。这里的绑定参数只有 1 个变量,我用逗号将它们很好地分开(为了模仿列表)。查看此光学文件会说这看起来不错,但我认为绑定参数语句确实需要单独的变量。此时它实际上只看到一个变量,而不是我的测试用例中的 4 个。
我试过这样循环:
mysqli_stmt_bind_param($stmt, $notation,
foreach ($fields as $field => $value) {
echo $value['value'];
if ($countfields != $i ) {
echo ",";
}
}
);
但是没有用,因为它会吐出以下内容。
Parse error: syntax error, unexpected 'foreach' (T_FOREACH) in
有人知道如何解决这个问题吗?
==编辑==
table 结构符合要求,虽然我怀疑是那个问题,因为我得到一个绑定参数错误,而不是执行语句时的错误。
== 编辑 2 ==
还尝试了以下方法,但没有帮助,因为它没有堆叠(我在 PDO 中看到了这个)
foreach ($fields as $field => $value) {
switch($value['notation']) {
case "int":
$notation = "i";
break;
case "string":
$notation = "s" ;
break;
}
mysqli_stmt_bind_param($stmt, $notation, $value['value']);
}
您需要将每个变量单独传递给 mysqli_stmt_bind_param
,因此 $parameters
需要是一个数组,而不是字符串。更改以下代码行:
$parameters = "";
至:
$parameters = array();
和
$parameters .= "'".$value['value']."'" ;
至:
$parameters[] = $value['value'];
(请注意,使用准备语句时无需转义值)
删除这一行:
$parameters .= ", ";
最后,改变
mysqli_stmt_bind_param($stmt, $notation, $parameters);
至:
mysqli_stmt_bind_param($stmt, $notation, ...$parameters);
它应该可以正常工作。