mysqli bind_param() 应该是一个参考,给定的值
Posted
技术标签:
【中文标题】mysqli bind_param() 应该是一个参考,给定的值【英文标题】:mysqli bind_param() expected to be a reference, value given 【发布时间】:2013-04-13 19:16:40 【问题描述】:不知道是什么导致了错误mysqli_stmt::bind_param() 的参数 3 应该是一个参考,在...中给出的值
PDO
$query = "INSERT INTO test (id,row1,row2,row3) VALUES (?,?,?,?)";
$params = array(1,"2","3","4");
$param_type = "isss";
$sql_stmt = mysqli_prepare ($mysqli, $query);
call_user_func_array('mysqli_stmt_bind_param', array_merge(array($sql_stmt, $param_type), $params));
mysqli_stmt_execute($sql_stmt);
也试过OOP
OOP
$insert_stmt = $mysqli->prepare($query);
array_unshift($params, $param_type);
call_user_func_array(array($insert_stmt, 'bind_param'), $params);
$insert_stmt->execute();
但同样的错误,只是现在参数 2 引起了问题。
那么,$params 有什么问题?我需要 $params 是一个值数组。
【问题讨论】:
你为什么用call_user_func_array
?
@MarcelKorpel 因为没有 mysqli 就无法使用
@MarcelKorpel 这太手动了,无法进行任何抽象。
@MarcelKorpel 使抽象成为可能。为了能够将任何数组绑定到任何查询,只需将它们作为参数传递给某个辅助函数,而不是直接在应用程序代码中编写所有这些大量的 bind_params,使其臃肿。
@MarcelKorpel 甚至根本没有任何帮助程序 - 但只是在 任意 大小的 $params
数组的情况下,这种情况经常发生。
【参考方案1】:
更新
这个答案已经过时了。请在较新的 php 版本中使用扩展运算符,如 Stacky 回答。
来自 php 文档:
将 mysqli_stmt_bind_param() 与 call_user_func_array() 结合使用时必须小心。请注意,mysqli_stmt_bind_param() 需要通过引用传递参数,而 call_user_func_array() 可以接受可以表示引用或值的变量列表作为参数。
在mysqli-stmt.bind-param页面上,您有不同的解决方案:
例如:
call_user_func_array(array($stmt, 'bind_param'), refValues($params));
function refValues($arr)
if (strnatcmp(phpversion(),'5.3') >= 0) //Reference is required for PHP 5.3+
$refs = array();
foreach($arr as $key => $value)
$refs[$key] = &$arr[$key];
return $refs;
return $arr;
【讨论】:
自从升级到 php 7.1 后,这不再对我有用 Asa Carter,您找到 PHP 7 的解决方案了吗?使用 PHP 7 遇到同样的问题 @MindaugasLi 您可以尝试将其与反射一起使用:http://php.net/manual/de/mysqli-stmt.bind-param.php#104073 使用另一个答案中提到的扩展运算符(...)是一个更清洁的解决方案。 我在编辑的文件中看到相同的代码是巧合吗?我认为不是【参考方案2】:在 PHP 5.6 中引入,您可以使用 ...
operator ("spread operator") 以更少的麻烦达到相同的结果:
//object-oriented
$sql_stmt->bind_param($param_type, ...$params);
//procedural
mysqli_stmt_bind_param($sql_stmt, $param_type, ...$params);
【讨论】:
比使用call_user_func_array
函数的方法更简洁。
这是所有人的解决方案。简单,随处工作
什么是param_type
?那里有什么?
@TheRealChx101 这个答案中的变量来自上面的原始问题。所以在这种情况下,$param_type
是 "isss"
和 $params
是 array(1,"2","3","4")
。【参考方案3】:
不知道为什么代码中有“PDO”这个词,但这是其中唯一正确的词。使用PDO,并且使用 mysqli 准备好的语句不会遇到问题:
$query = "INSERT INTO test (id,row1,row2,row3) VALUES (?,?,?,?)";
$params = array(1,"2","3","4");
$stmt = $pdo->prepare($query);
$stmt->execute($params);
只要看看这个干净简洁的代码,然后将它与你需要的带有 mysqli 准备语句的代码进行比较。
【讨论】:
execute
所有参数都被视为字符串。否则,您需要 PDO 的 bindParam
或 bindValue
,这并没有太大的区别。虽然我也更喜欢 PDO 而不是 mysqli。
这不是什么大问题,你知道的。不过,如果您想要使用传统 SQL 进行严格的类型转换和简洁的代码,您可以使用 SafeMysql 以及类型提示占位符的绝妙想法
您的“出色”课程不适用于真正的准备好的语句。
@redreggae 我发现该类与准备好的语句一样好......是的,你的常识的想法对于 mysql 来说是非常好的和安全的,但在 php5.5 的情况下它不会有用,因为不支持 mysql_* 函数
@YourCommonSense 对我来说,让 dbms 进行转义似乎更简单,并且如果我需要它,那么具有速度优势也很好。汉隆的剃须刀,我的朋友。以上是关于mysqli bind_param() 应该是一个参考,给定的值的主要内容,如果未能解决你的问题,请参考以下文章
在 $bind_param() 中动态绑定参数; mysqli
如何将mysqli :: bind_param与数组一起用作第二个参数
PHP / MySQLi - 数组作为 bind_param
mysqli_stmt::bind_param() - 为每个参数指定另一个数据类型而不是“s”