请参阅下面的代码。 我试图将参数数组绑定到我准备好的语句中。 我一直在网上浏览,可以看到我必须使用call_user_func_array,但无法让它工作。我得到的错误是: “第一个参数预计将是一个有效的回调,'数组'给出了” 我可能错了,但我假设第一个参数可能是一个数组,也许这个错误信息是误导性的。我认为问题是我的阵列在某种程度上是错误的。 谁能看到我做错了什么?感谢。
$type = array("s", "s");
$param = array("string1","anotherstring");
$stmt = $SQLConnection->prepare("INSERT INTO mytable (comp, addl) VALUES (?,?)");
$params = array_merge($type, $param);
call_user_func_array(array(&$stmt, 'bind_param'), $params);
$SQLConnection->execute();
答案 0 :(得分:17)
必须是这样的:
//connect
$mysqli = new mysqli($host, $user, $password, $db_name);
//prepare
$stmt = $mysqli->prepare("SELECT * FROM the_table WHERE field1= ? AND Field2= ?");
//Binding parameters. Types: s = string, i = integer, d = double, b = blob
$params= array("ss","string_1","string_2");
//now we need to add references
$tmp = array();
foreach($params as $key => $value) $tmp[$key] = &$params[$key];
// now us the new array
call_user_func_array(array($stmt, 'bind_param'), $tmp);
$stmt->execute();
/* Fetch result to array */
$res = $stmt->get_result();
while($row = $res->fetch_array(MYSQLI_ASSOC)) {
$a_data[]=$row;
}
print_r($a_data);
$stmt->close();
答案 1 :(得分:9)
我不知道为什么你必须使用call_user_func_array
,但这是另一个故事。
在我眼中唯一可能出错的是你正在使用对象的引用。假设你使用的是PHP 5. *,那就没必要了:
call_user_func_array(array($stmt, 'bind_param'), $params);
答案 2 :(得分:4)
自 PHP 5.6 以来,您不必再使用call_user_func_array()
了。
而不是:
$stmt->bind_param($param_types, $my_params_array);
您可以使用splat operator,如下所示:
$stmt->bind_param($param_types, ...$my_params_array); // exact code
答案 3 :(得分:1)
无法在我自己的问题上回答这个问题,因为它被标记为欺骗:here。但我认为我的最终解决方案,使用此问题中的答案,适用于我的用例,可能对某人有帮助。
我的目标是获取一组已发布的ID并在NOT IN
MYSQL语句中使用它们。假设发布了5个ID的数组。
计算发布的ID号,以构建?
语句的NOT IN
占位符。使用$params_count = substr(str_repeat(',?', count($array_of_ids)), 1);
给出结果:(?,?,?,?,?)
将在SQL语句中使用。
创建带有ID并输入i
或s
等的函数。对我来说,它们都是i
所以我的功能更简单。返回类似于此$params= array("iiiii",1,2,3,4,5)
的数组,其中第一个值是i
的集合,后续值是ID,取决于传入函数的总ID。
function build_bind_params($values, $bind_type) {
$s = substr(str_repeat($bind_type, count($values)), 0);
$bind_array = array();
$bind_array[] = $s;
foreach($values as $value) {
$bind_array[] = $value;
}
return $bind_array;
}
$params = build_bind_params($array_of_ids, "i");
然后使用foreach ($params as $key => $value) $tmp[$key] = &$params[$key];
正确格式化新创建的$params
以进行绑定。
然后使用call_user_func_array(array($stmt , 'bind_param') , $tmp);
正确绑定数组。
然后执行$stmt
答案 4 :(得分:1)
在将类型与值集合在一起之前,上述大多数都不是解决方案,而是将它们添加到call_user_func_array()之前。这个解决方案对我有用:
/* create a database connection */
$db = new mysqli($host, $user, $password, $db_name);
/* setup the sql, values, and types */
$sql="SELECT * FROM languages
WHERE language_code = ?
AND charset = ?
ORDER BY native_name";
$values = array($langCode, $charset);
$types = "ss";
/* pass those variables to the execute() function defined below */
if ($rows = execute($sql, $values, $types))
{
return $rows[0];
}
function execute($sql, $values='', $types='')
{
/* prepare the sql before binding values and types */
$stmt = $db->prepare($sql);
/*combine the values and types into $inputArray */
$inputArray[] = &$types;
$j = count($values);
for($i=0;$i<$j;$i++){
$inputArray[] = &$values[$i];
}
/* add the combined values and types to call_user_func_array() for binding */
call_user_func_array(array($stmt, 'bind_param'), $inputArray);
$result = $stmt->execute();
return $result;
}
以下是对此示例所基于的完整描述的引用: http://big.info/2015/08/php-use-call_user_func_array-for-variable-number-of-parameters-arrays-in-prepared-statements.html
答案 5 :(得分:0)
为什么要调用call_user_func_array(array($ statement,'bind_param'),$ bind_arguments)?因为$ bind_arguments是一个数组。你得到一个函数将一个语句绑定到它查询的参数,无论你有多少参数。
良好代码示例......
<?php
# link
$dblink = new mysqli('HOSTNAME','USERNAME','PASSWORD','DATABASENAME');
# example data
$statement = $dblink->prepare("SELECT * from Person WHERE FirstName = ? AND MiddleName = ? AND LastName = ? and Age = ?");
$recordvalues = ['John', 'H.', 'Smith', 25];
$sqlbindstring = "sssi"; # String, String, String, Integer example
# make the references
$bind_arguments = [];
$bind_arguments[] = $sqlbindstring;
foreach ($recordvalues as $recordkey => $recordvalue)
{
$bind_arguments[] = & $recordvalues[$recordkey]; # bind to array ref, not to the temporary $recordvalue
}
# query the db
call_user_func_array(array($statement, 'bind_param'), $bind_arguments); # bind arguments
$statement->execute(); # run statement
$result = $statement->get_result(); # get results
# get the results
if($result) {
while ($row = $result->fetch_assoc()) {
print("\n\nMy row is...");
print_r($row);
}
}
?>
错误代码示例......
<?php
# Same setup as above..
$statement->prepare("SELECT * from Person WHERE FirstName = ? AND MiddleName = ? AND LastName = ? and Age = ?");
$statement->bind('John', 'H.", 'Smith', 25);
?>
在第一个示例中:您可以向要完成的绑定传递尽可能多的内容,这样就可以在整个应用程序中的一行中调用bind()。这很好地扩展。
在第二个示例中:您必须为数据库中每个可能的记录为每个可能的插入组编写一个bind()语句。这很难扩展。
答案 6 :(得分:0)
如果您收到错误,请尝试以下操作:
call_user_func_array(array($stmt, 'bind_param'), refValues($params));
function refValues($arr){
if (strnatcmp(phpversion(),'5.3') >= 0) {
$refs = array();
foreach($arr as $key => $value)
$refs[$key] = &$arr[$key];
return $refs;
}
return $arr;
}