PHP 5.3.1 传递引用问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2045875/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:47:38  来源:igfitidea点击:

Pass by reference problem with PHP 5.3.1

referencemysqliphp

提问by Spot

Ok, this is a weird problem, so please bear with me as I explain.

好的,这是一个奇怪的问题,所以请耐心等待我的解释。

We upgraded our dev servers from PHP 5.2.5 to 5.3.1.

我们将开发服务器从 PHP 5.2.5 升级到 5.3.1。

Loading up our code after the switch, we start getting errors like:

在切换后加载我们的代码,我们开始收到如下错误:

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

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

the line mentioned (105) is as follows:

提到的行(105)如下:

call_user_func_array(Array($stmt, 'bind_param'), $passArray);

we changed the line to the following:

我们将该行更改为以下内容:

call_user_func_array(Array($stmt, 'bind_param'), &$passArray);

at this point (because allow_call_time_pass_reference) is turned off, php throws this:

此时(因为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

Deprecated: Call-time pass-by-reference has been deprecated in /home/spot/trunk/system/core/Database.class.php on line 105

After trying to fix this for some time, I broke down and set allow_call_time_pass_referenceto on.

在尝试解决这个问题一段时间后,我崩溃了并开始allow_call_time_pass_reference了。

That got rid of the Deprecatedwarning, but now the Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a referencewarning is throwing every time, with or withoutthe referencing.

这消除了Deprecated警告,但现在Warning: Parameter 2 to mysqli_stmt::bind_param() expected to be a reference警告每次都会抛出,无论是否有引用。

I have zero clue how to fix this. If the target method was my own, I would just reference the incoming vars in the func declaration, but it's a (relatively) native method (mysqli).

我零线索如何解决这个问题。如果目标方法是我自己的,我只会在 func 声明中引用传入的变量,但它是一个(相对)本机方法 (mysqli)。

Has anyone experienced this? How can I get around it?

有没有人经历过这个?我怎样才能绕过它?

Thank you.

谢谢你。

采纳答案by Zak

You are passing an array of elements ($passArray). The second item insidethe passed array needs to be a reference, since that is really the list of items you are passing to the function.

您正在传递一个元素数组 ($passArray)。第二项传递的数组必须是一个参考,因为这真的是你传递给函数的项目列表。

回答by Dominic

I just experienced this same problem, calling bind_param via call_user_func_array and passing an array of parameters. The solution is to modify the values in the array to be referenced. It's not elegant but it works.

我刚刚遇到了同样的问题,通过 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;

}

回答by Andrew Moore

Actually, be aware that there is a bug with PHP 5.3.1 concerning references and all callfamily of functions:

实际上,请注意 PHP 5.3.1 存在一个关于引用和所有call函数系列的错误:

PHP Bugs #50394: Reference argument converted to value in __call

PHP 错误 #50394:引用参数在 __call 中转换为值

The behavior you are seeing might be a result of this bug and any attempt to fix it code wise may cause problems in the long run.

您看到的行为可能是此错误的结果,从长远来看,任何以代码方式修复它的尝试都可能导致问题。

The problem has been fixed in the SVN version of PHP. Until 5.3.2 is released, you may compile a new version for use, or downgrade to an earlier version.

该问题已在 SVN 版本的 PHP 中修复。在 5.3.2 发布之前,您可以编译新版本使用,也可以降级到旧版本。

回答by leek

We were experiencing this same problem with this code:

我们在使用此代码时遇到了同样的问题:

call_user_func(array($strCartHandler, 'CartPurchaseEvent'), $strCartEvent, $objToUser, null, $this);

My solution was to just skip call_user_funcaltogether and do this:

我的解决方案是call_user_func完全跳过并执行以下操作:

$strCartHandler::CartPurchaseEvent($strCartEvent, $objToUser, null, $this);

回答by Louis

I think what is deprecated is passing a reference through a function. In the function definition you do something like:

我认为不推荐使用的是通过函数传递引用。在函数定义中,您可以执行以下操作:

function(&$arg) {

}

This doesn't help you much but you probably need not pass the reference anyway. I guess you could try a wrapper function.

这对您没有多大帮助,但无论如何您可能不需要传递参考。我想你可以尝试一个包装函数。

function wrapper($stmt, &$passArray) {
    call_user_func_array($stmt, $passArray);
}

回答by Fatalist

This will helps:

这将有助于:

<?php
call_user_func_array(Array($stmt, 'bind_param'), array(&$passArray));

function bind_param ($val)
{
    $val = (is_array($val)) ? $val[0] : $val;

    // operations...
}

?>

回答by Kotaries

I've got a similar problem, the current code didnt work:

我遇到了类似的问题,当前代码不起作用:

$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);
...

It told that "Parameter 2 to mysqli_stmt::bind_param() expected to be a reference, value given"

它告诉“mysqli_stmt::bind_param() 的参数 2 应该是一个参考,给定的值”

And then, in despair, I've tried to take $from_var and $to_var in quotes. And it worked!

然后,在绝望中,我试图将 $from_var 和 $to_var 放在引号中。它奏效了!

$params=Array('ii');
array_push($params,"$from_var");
array_push($params,"$to_var");

Hope, it will help somebody, good luck :)

希望,它会帮助某人,祝你好运:)

回答by Bill Karwin

I think the mysqli_bind_param()and mysqli_bind_result()functions are very awkward to use. I've encountered the same difficulty as you describe using them in combination with call_user_func_array()

我觉得mysqli_bind_param()mysqli_bind_result()函数用起来很别扭。我遇到了与您描述的将它们结合使用的相同困难call_user_func_array()

My workaround was to stop using mysqli and instead use PDO_mysql. It has a much easier usage:

我的解决方法是停止使用 mysqli,而是使用 PDO_mysql。它有一个更简单的用法:

$pdoStmt->execute( $passArray );

回答by DeveloperChris

The second paramer Must be an array. apparently this was only enforced in 5.3

第二个参数必须是一个数组。显然这仅在 5.3 中强制执行