Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass by reference problem with PHP 5.3.1

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.

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

the line mentioned (105) is as follows:

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:

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_reference to on.

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

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

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

Thank you.

like image 350
Spot Avatar asked Jan 12 '10 00:01

Spot


People also ask

Does PHP pass by reference?

TL;DR: PHP supports both pass by value and pass by reference. References are declared using an ampersand ( & ); this is very similar to how C++ does it.

What does &$ mean in PHP?

passing argument through reference (&$) and by $ is that when you pass argument through reference you work on original variable, means if you change it inside your function it's going to be changed outside of it as well, if you pass argument as a copy, function creates copy instance of this variable, and work on this ...

What is pass by value and pass by reference in PHP?

In PHP, arguments to a function can be passed by value or passed by reference. By default, values of actual arguments are passed by value to formal arguments which become local variables inside the function. Hence, modification to these variables doesn't change value of actual argument variable.

What is Call by reference in PHP?

In case of PHP call by reference, actual value is modified if it is modified inside the function. In such case, you need to use & (ampersand) symbol with formal arguments. The & represents reference of the variable. Let's understand the concept of call by reference by the help of examples.


4 Answers

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(array($stmt, 'bind_param'), makeValuesReferenced($passArray));  function makeValuesReferenced($arr){     $refs = array();     foreach($arr as $key => $value)         $refs[$key] = &$arr[$key];     return $refs;  } 
like image 108
Dominic Avatar answered Sep 21 '22 22:09

Dominic


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

like image 23
Zak Avatar answered Sep 20 '22 22:09

Zak


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

PHP Bugs #50394: Reference argument converted to value in __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.

like image 33
Andrew Moore Avatar answered Sep 21 '22 22:09

Andrew Moore


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_func altogether and do this:

$strCartHandler::CartPurchaseEvent($strCartEvent, $objToUser, null, $this);
like image 23
leek Avatar answered Sep 19 '22 22:09

leek