2

我正在尝试将几个参数动态传递给 bind_param() 函数。

这是我收到的错误:

警告:mysqli_stmt::bind_param() 的参数 2 应为参考,给定值

代码:

$con = new mysqli('localhost',USER,PASS,DBS);

if(mysqli_connect_errno()) {
error(mysqli_connect_errno());
}

$con -> set_charset("utf8");

/*inside*/

$type='';

$query='SELECT bugID FROM bug';

if(!empty($_GET['cena'])) {

    $build[]='uCena=?';

    $type.='i';
    $val[]=$_GET['cena'];

}

if(!empty($_GET['popust'])) {

    $build[]='uPopust=?';

    $type.='i';
    $val[]=$_GET['popust'];

}

if(!empty($build)) {

    echo $query .= ' WHERE '.implode(' AND ',$build);
}

$new = array_merge(array($type),$val);
foreach($new as $key => $value)
{
    $tmp[$key]=&$new[$key];

    }

echo '<br/><br/>';

foreach ($new as $new ){

    echo "$new<br/>";
}

if ($count = $con->prepare($query)) {

    call_user_func_array(array($count,'bind_param'),$tmp);
    $count->execute();
    $cres = $count->fetch_row();

    $count -> close();

} else error($con->error);


/*inside*/

$con -> close();
4

1 回答 1

6

我很抱歉这么说,但你的代码很糟糕。它是不可读的,并且在生产环境中很难维护。

一个例子:你在哪里使用这些行:

foreach($new as $key => $value)
{
    $tmp[$key]=&$new[$key];
}

你可以使用:

foreach($new as $key => $value)
{
    $tmp[$key]= $value;
}

这将显示您对 foreach 语句的理解。此外,使用更具描述性的变量名称比$tmp并大大$new提高代码的可读性。您的代码还有很多问题,但让我们专注于这个问题。

主要问题在这一行:

if ($count = $con->prepare($query)) {

这行:

call_user_func_array(array($count,'bind_param'),$tmp);

mysqli::prepare() 返回一个 mysqli_statement (如此处所述,而不是某种计数。$count = count($tmp)如果您需要确定参数的数量,请尝试使用。

您看到的错误是您使用call_user_func_array(). 如bind_param 上的 PHP.net 页面所述:

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

最佳解决方案在同一页面的评论中提供:

在 PHP 版本 5.3+ 中通过 call_user_func_array() 使用动态数量的参数调用 mysqli::bind_param() 时,除了使用额外的函数来构建数组元素的引用之外,还有另一种解决方法。您可以使用反射来调用 mysqli::bind_param()。当使用 PHP 5.3+ 时,与将数组传递给您自己的引用生成器函数相比,这可以节省大约 20-40% 的速度。

例子:

<?php 
$db     = new mysqli("localhost","root","","tests"); 
$res    = $db->prepare("INSERT INTO test SET foo=?,bar=?"); 
$refArr = array("si","hello",42); 
$ref    = new ReflectionClass('mysqli_stmt'); 
$method = $ref->getMethod("bind_param"); 
$method->invokeArgs($res,$refArr); 
$res->execute();  
?>

希望这可以帮助。

于 2013-08-12T21:51:40.400 回答