PHP 5.3.1 的引用传递问题
Posted
技术标签:
【中文标题】PHP 5.3.1 的引用传递问题【英文标题】:Pass by reference problem with PHP 5.3.1 [duplicate] 【发布时间】:2011-01-03 23:46:10 【问题描述】:好的,这是一个奇怪的问题,所以请耐心等待我解释。
我们将开发服务器从 php 5.2.5 升级到 5.3.1。
在切换后加载我们的代码,我们开始收到如下错误:
Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference, value given in /home/spot/trunk/system/core/Database.class.php on line 105
提到的行(105)如下:
call_user_func_array(Array($stmt, 'bind_param'), $passArray);
我们将这一行更改为:
call_user_func_array(Array($stmt, 'bind_param'), &$passArray);
此时(因为allow_call_time_pass_reference
)被关闭,php抛出这个:
Deprecated: Call-time pass-by-reference has been deprecated in /home/spot/trunk/system/core/Database.class.php on line 105
在尝试修复此问题一段时间后,我崩溃并将allow_call_time_pass_reference
设置为开启。
这消除了Deprecated
警告,但现在Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference
警告每次都会抛出,有或没有引用。
我对如何解决这个问题一无所知。如果目标方法是我自己的,我只会在 func 声明中引用传入的 var,但它是(相对)本机方法(mysqli)。
有人经历过吗?我怎样才能绕过它?
谢谢。
【问题讨论】:
另外,在上面的代码中 $stmt 是一个从 mysqli::prepare 返回的对象 我也遇到了这个问题,发现this的博文对我帮助很大。 【参考方案1】:我也遇到了类似的问题,目前的代码不起作用:
$query="Select id,name FROM mytable LIMIT ?,?";
$params=Array('ii');
array_push($params,$from_var);
array_push($params,$to_var);
...
$stmt=$link->prepare("$query");
$ref=new ReflectionClass('mysqli_stmt');
$method=$ref->getMethod("bind_param");
$method->invokeArgs($stmt,$params);
...
它告诉“mysqli_stmt::bind_param() 的参数 2 应该是一个参考,给定的值”
然后,我绝望地尝试将 $from_var 和 $to_var 放在引号中。它奏效了!
$params=Array('ii');
array_push($params,"$from_var");
array_push($params,"$to_var");
希望对某人有所帮助,祝你好运:)
【讨论】:
【参考方案2】:您正在传递一个元素数组 ($passArray)。传递的数组内部的第二个项目需要是一个引用,因为这实际上是您传递给函数的项目列表。
【讨论】:
其实你是对的。但是,引用该 var 也无济于事。嗯 好的,通过创建一个虚拟数组来解决这个问题,引用来自 main 的值。很遗憾,这必须是诚实的。 :) 谢谢! 亲爱的,我也有类似的问题。你有什么建议吗? ***.com/questions/23290490/… 这个答案正确地识别了问题,但肯定看到@Dominic的以下答案以获得解决方案。【参考方案3】:第二个参数必须是一个数组。显然这仅在 5.3 中强制执行
【讨论】:
【参考方案4】:这会有所帮助:
<?php
call_user_func_array(Array($stmt, 'bind_param'), array(&$passArray));
function bind_param ($val)
$val = (is_array($val)) ? $val[0] : $val;
// operations...
?>
【讨论】:
【参考方案5】:我们在这段代码中遇到了同样的问题:
call_user_func(array($strCartHandler, 'CartPurchaseEvent'), $strCartEvent, $objToUser, null, $this);
我的解决方案是完全跳过 call_user_func
并执行以下操作:
$strCartHandler::CartPurchaseEvent($strCartEvent, $objToUser, null, $this);
【讨论】:
【参考方案6】:实际上,请注意 PHP 5.3.1 存在一个关于引用和所有 call
系列函数的错误:
PHP Bugs #50394: Reference argument converted to value in __call
您看到的行为可能是此错误的结果,任何以代码方式修复它的尝试从长远来看都可能会导致问题。
该问题已在 SVN 版本的 PHP 中得到修复。在 5.3.2 发布之前,您可以编译新版本使用,也可以降级到更早的版本。
【讨论】:
【参考方案7】:我刚刚遇到了同样的问题,通过 call_user_func_array 调用 bind_param 并传递了一个参数数组。解决方法是修改要引用的数组中的值。它并不优雅,但它有效。
call_user_func_array(array($stmt, 'bind_param'), makeValuesReferenced($passArray));
function makeValuesReferenced($arr)
$refs = array();
foreach($arr as $key => $value)
$refs[$key] = &$arr[$key];
return $refs;
【讨论】:
【参考方案8】:我认为不推荐使用的是通过函数传递引用。在函数定义中,您可以执行以下操作:
function(&$arg)
这对您没有多大帮助,但您可能无论如何都不需要传递参考。我想你可以尝试一个包装函数。
function wrapper($stmt, &$passArray)
call_user_func_array($stmt, $passArray);
【讨论】:
【参考方案9】:我认为mysqli_bind_param()
和mysqli_bind_result()
函数使用起来很尴尬。我遇到了与您将它们与call_user_func_array()
结合使用时描述的相同的困难
我的解决方法是停止使用 mysqli,而是使用 PDO_mysql。它的用法要简单得多:
$pdoStmt->execute( $passArray );
【讨论】:
我认为 PDO_mysql 已被弃用? 不,一点也不。到底是什么让你产生了这个想法? @Spot:php_mysql.so
不推荐(不弃用),pdo_mysql.so
非常推荐。以上是关于PHP 5.3.1 的引用传递问题的主要内容,如果未能解决你的问题,请参考以下文章