【发布时间】:2019-12-26 22:15:12
【问题描述】:
我正在编写一个函数,我可以在其中执行几个数据库操作,在本例中是基于简单数组的插入数据
"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():类型定义字符串中的元素个数 与 .... 第 647 行中的绑定变量数不匹配
过了一会儿,我意识到参数变量就是这种情况。这里的 bind 参数只有 1 个变量,我用逗号很好地将它们分开(为了模仿列表)。查看这个光学会说这看起来不错,但是我认为绑定参数语句确实需要单独的变量。此时它实际上只看到一个变量,而不是我的测试用例中的 4。
我试过这样循环:
mysqli_stmt_bind_param($stmt, $notation,
foreach ($fields as $field => $value) {
echo $value['value'];
if ($countfields != $i ) {
echo ",";
}
}
);
但无济于事,因为它会吐出以下内容。
解析错误:语法错误,意外'foreach' (T_FOREACH) in
有人知道如何解决这个问题吗?
== 编辑 ==
请求的表结构,虽然我怀疑是那个问题,因为我得到一个绑定参数错误,而不是执行语句时的错误。
== 编辑 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']);
}
【问题讨论】:
-
你的数据库结构是什么样的?
-
这与我的数据库无关,它纯粹是那部分,因为我可以毫无问题地填写我的角色表(它只是一个 id 和一个描述,然后我只输入描述)。如果您必须知道,我添加了它的结构图片,此时非常简单@gview
-
附带说明一下,使用 PDO 甚至更好的东西(例如 DB 抽象类)会更容易,例如EasyDB。
-
我强烈建议您看看phpdelusions.net/mysqli/simple 上的一些教程,如果您已经被它所困扰,他们会解释如何正确使用 mysqli。
-
好的。查看
password_hash()和其中的相关链接。也不需要加盐,它会处理所有这些。另外,如果您使用的是 PHP 7,则可以从使用更强大的 Argon2 中受益。
标签: php mysqli prepared-statement