【问题标题】:PHP,mysqli : Dynamic prepared statement not worksPHP,mysqli:动态准备语句不起作用
【发布时间】:2016-09-03 19:54:06
【问题描述】:

我需要为网页创建动态查询。用户可以选择他们想要搜索的类别(SQL 数据库中的列名)以及他们要查找的值是什么。我在 stackoverflow 和其他网站上浏览了一些类似的帖子,但我找不到解决方案。我使用下面的代码(它是为了测试,所以我在类别名称和值中写了类别)。如果我不尝试动态绑定参数查询效果很好,我可以打印 $tester 数组的值。这个问题的解决方案是什么?我想问题出在“call_user_func_array ...”部分。

$stmt = mysqli_stmt_init($conn);
//The category names and variable names
$cat1 = "LCVAR";
$cat2 = "APOLG";
$LCVAR = "KALOCSA";
$APOLG = "magyar";
//creating the statement
$statement = "SELECT VNEV,KNEV FROM TORZS WHERE ";
$statement = $statement . " " . $cat1 . " ". "=?". " ". "AND" . " ";
$statement = $statement . " " . $cat2 . " ". "=?";
//SELECT VNEV,KNEV FROM TORZS WHERE LCVAR =? AND APOLG =?
mysqli_stmt_prepare($stmt,$statement);
$a_params = array();
$a_param_type = array("s","s");
$a_bind_params = array($cat1 => $LCVAR,$cat2 => $APOLG);
$param_type = '';
// creating array for call_user_function_array
$n = count($a_param_type);
for($i = 0; $i < $n; $i++) {
$param_type .= $a_param_type[$i];
} 
$a_params[] = &$param_type;
for($i = 0; $i < $n; $i++) {
$a_params[] = &$a_bind_params[$i];
}
call_user_func_array(array($stmt,'mysqli_stmt_bind_param'),$a_bind_params);
mysqli_stmt_execute($stmt);
$result = array();
mysqli_stmt_bind_result($stmt, $result['VNEV'], $result['KNEV']);
$tester = array();
while(mysqli_stmt_fetch($stmt)){
$tester[] = array($result['VNEV'],$result['KNEV']) ;
}

编辑 1:

print_r($stmt) 的结果:

  mysqli_stmt Object 
     ( [affected_rows] => 0 
       [insert_id] => 0 
       [num_rows] => 0 
       [param_count] => 2 
       [field_count] => 2 
       [errno] => 0 
       [error] => 
       [error_list] => Array ( ) 
       [sqlstate] => 00000 
       [id] => 1 )

print_r($a_bind_params) 的结果:

      Array ( [LCVAR] => KALOCSA
              [APOLG] => magyar ) 

【问题讨论】:

  • 有什么问题? “不起作用”非常模糊。你做了什么来调试它?在将生成的查询传递给mysqli_stmt_prepare 之前,您是否查看过它们是否正确?
  • 是的,我检查了查询。如果我不尝试动态绑定参数并且在“静态”语句中给出参数,那么一切正常。我想问题可能出在 'call_user_func_array(array($stmt,'mysqli_stmt_bind_param'),$a_bind_params)' 部分。
  • 我之前写过,查询本身在这种状态下工作正常。当我想使用动态参数绑定并且我使用 call_user_func_array 时,问题就开始了。

标签: php mysql mysqli prepared-statement


【解决方案1】:

来自PHP Manual page for bind_param

注意:

将 mysqli_stmt_bind_param() 与 call_user_func_array() 结合使用时必须小心。注意 mysqli_stmt_bind_param() 需要传递参数 引用,而 call_user_func_array() 可以接受作为参数 a 可以表示引用或值的变量列表。

除此之外,没有人可以为您提供更清晰的解决方案,因为您需要准确地告诉我们问题出在哪里,您的PHP error log 告诉您什么以及您的MySQLi stmt error 说什么。

如果您可以输出您的 SQL 查询实际是什么 (print_r($stmt)) 以及您的绑定参数实际是什么 (print_r($a_bind_params)),这对您自己和我们也可能会有所帮助。

编辑您的问题并添加这些详细信息,我确信解决方案将是显而易见的。


P.s 正如 Fred-ii 所引用的,您可以通过以下方式简化您的 $statement

 $statement = $statement . " " . $cat1 . " ". "=?". " ". "AND" . " ";

成为:

 $statement .= " " . $cat1 . " ". "=?". " ". "AND" . " ";

并且每次(我可以看到两次)您声明的变量值包含变量之前的值时应用它,这就是 .= 语法为您所做的。

【讨论】:

  • 在这种情况下,我该怎么做才能解决这个问题?我对 PHP 很陌生。
  • 按照我在回答中的建议,列出您的 MySQLi 错误和 PHP 错误,然后在 Stack Overflow 搜索bind_param 问题的解决方案,如果这是原则错误,你不会是第一个遇到这个问题的人。 @IstvánBarna
  • 谢谢! print_r($stmt) 的结果:mysqli_stmt Object ([affected_rows] => 0 [insert_id] => 0 [num_rows] => 0 [param_count] => 2 [field_count] => 2 [errno] => 0 [error] => [error_list] => Array ( ) [sqlstate] => 00000 [id] => 1 ) print_r($a_bind_params) 的结果:Array ( [LCVAR] => KALOCSA [APOLG] => magyar )
  • @IstvánBarna 编辑您的问题并将这些详细信息更新到您的问题中。 cmets中的代码很难阅读。
  • @IstvánBarna 我看到了,这很好。您的更新显示 SQL 中没有错误,请阅读[errno] =&gt; 0,因此您需要查找您的错误是否在 PHP 代码中
猜你喜欢
  • 2013-03-24
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 2015-01-05
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 2013-07-23
相关资源
最近更新 更多