【发布时间】:2017-11-15 13:43:03
【问题描述】:
我之前的问题已关闭,因为他们说这是重复的,但重复的帖子没有回答我的问题。所以我又来了,我在编辑部分添加了一些额外的 cmets 来说明为什么重复的帖子对我没有帮助。
我正在尝试动态构造一个准备好的语句,但我不断收到以下错误:
mysqli_stmt_bind_param():类型定义字符串中的元素个数 与
中的绑定变量数不匹配
当我回显我的语句时,类型定义的数量与绑定变量匹配,所以我不知道出了什么问题。我认为我的代码可能是在传递字符串、引号或其他东西而不是变量,但我是准备好的语句的新手,不知道如何检查我的查询。当使用简单的mysqli_query 时,我可以回显查询并查看我的错误所在。我不确定如何使用准备好的语句来做到这一点,所以我希望有人可以帮助发现我的错误。
我正在尝试动态构造 prepare 语句,以便我可以重用代码,如下所示:
$db = mysqli_stmt_init($dbconnection);
// I have looped through my fields and constructed a string that when
// echoed returns this:
// ?, ?, ?, ?,
// I use sub str just to remove the last comma and space leaving me
// with the string
// ?, ?, ?, ?.
// Ive echoed this to the browser to make sure it is correct.
$preparedQs = substr($preparedQs, 0, -2);
// I then loop through each field using their datatype and constructs
// the type string as follows ssss. Ive echoed this to the browser to
// make sure it is correct.
$preparedType = 'ssss';
// I then loop through my post array verifying and cleaning the data
// and then it constructing a string of clean values that results in
// Mike, null, Smith, Sr., (First, Middle, Last, Suffix) I use substr
// again just to remove the last comma and space. Ive echoed this to
// the browser to make sure it is correct.
$cleanstr = substr($cleanstr, 0, -2);
// I then explode that string into a an array that I can loop through
// and assign/bind each value to a variable as follows and use substr
// again to remove last comma and space.
$cleanstr = explode(", ", $cleanstr);
$ct2 = 0;
foreach ( $cleanstr as $cl){
$name = "a".$ct2;
$$name = $cl;
$varstr .= "$".$name.", ";
$ct2 = $ct2 +1;
}
$varstr = substr($varstr, 0, -2);
// I've echoed the $varstr to the browser and get $a1, $a2, $a3, $a4.
// I have also echo their value outside of the loop and know values
// have been assigned.
// I then try to assign each step above the appropriate
// prepared statement place holder
$stmt = mysqli_stmt_prepare($db, "INSERT INTO Contacts VALUES (". $preparedQs. ")");
mysqli_stmt_bind_param($db, "'".$preparedType."'", $varstr);
mysqli_stmt_execute($stmt);
我不确定自己做错了什么,因为当我回显 $preparedQs、$preparedType 和 $varstr 它们都有相同数量的元素但我得到“mysqli_stmt_bind_param(): Number of类型定义字符串中的元素与...中的绑定变量数不匹配”错误。我所能想到的只是我有引号或不应该的东西,但我尝试在某些区域添加和删除引号并且无法解决错误。
另外,我阅读了一些关于在准备好的语句中传递 null 的帖子,但即使我将 null 替换为实际值,我仍然得到同样的错误。
可能值得注意的是,当使用简单的程序 mysqli_query 和 mysqli_real_escape_string 清理我的数据时,一切正常。我试图通过将我的应用程序转换为准备好的语句来提高我的安全性,只是为了增加安全性。
这个问题的不同有两个原因
我使用的是过程编码,而不是对象或 PDO。因此,作为准备好的语句的新手,给出的示例即使在尝试理解它们之后也无济于事。
我使用的是插入语句,而不是选择或更新语句,在程序 php 中,查询字符串的写入方式与插入语句与选择或更新语句不同。
//更新代码
global $dbconnection;
if(!$dbconnection){
die("Function wm_dynamicForm connection failed.</br>");
} else {
//echo "</br>Function wm_connectionToDatabase connection success</br>";
}
$db = mysqli_stmt_init($dbconnection);
$preparedQs = substr($preparedQs, 0, -2); //removes the end , from my string
$cleanstr = substr($cleanstr, 0, -2); //removes the end , from my string
$cleanstr = explode(", ", $cleanstr);
$ct = 0;
foreach ( $cleanstr as $cl){
$items[] = array(
'a'.$ct => $cl,
);
$ct = $ct + 1;
}
$stmt = mysqli_stmt_prepare($db, "INSERT INTO Contacts VALUES (". $preparedQs. ")");
mysqli_stmt_bind_param($db, $preparedType, ...$items);
mysqli_stmt_execute($stmt);
if(!mysqli_stmt_execute($stmt)){
echo "Error: ".mysqli_error($db);
}
【问题讨论】:
标签: php mysql prepared-statement