Edit report at https://bugs.php.net/bug.php?id=52937&edit=1

 ID:                 52937
 Comment by:         lucas at threeamdesign dot com
 Reported by:        mryaggi at hotmail dot com
 Summary:            call_user_func warning is inappropriate
 Status:             Open
 Type:               Bug
 Package:            Scripting Engine problem
 Operating System:   Seven
 PHP Version:        5.3.3
 Block user comment: N
 Private report:     N

 New Comment:

to work around this problem put the reference in the argument array. e.g.:

function foo(&$bar) {
        $bar = 5;
}
$a = 1;
$b = 2;
call_user_func('foo', $a);
call_user_func_array('foo', array(&$b));
var_dump($a, $b);

gives

int(1)
int(5)


Previous Comments:
------------------------------------------------------------------------
[2010-10-11 11:00:54] mryaggi at hotmail dot com

Ok, I'm going to keep it simple.

You say "[I] have to use call_user_func_array instead".
Please show me how.

Note : I'm just trying to avoid the warning properly.

This would be quite a solution :
call_user_func('ExprectRef',               &   $p);
call_user_func_array('ExprectRef',array(   &   $p));

But it's a pity you have to write & TWICE. One in the signature, one in the 
call_user_func call. 

...it looks so much like the depreciated call-time pass-by-reference.

Don't you think?

------------------------------------------------------------------------
[2010-10-03 00:02:58] cataphr...@php.net

You *should* know whether the function takes references; it's part of its 
signature.

If it does take references you cannot use call_user_func, and have to use 
call_user_func_array instead.

------------------------------------------------------------------------
[2010-09-29 19:31:10] mryaggi at hotmail dot com

Thank you for your quick reply.
You say : "Use call_user_func_array()."
But you can run the test script with call_user_func_array() instad, and still 
you will get those warnings.

My point is : when you call call_user_func you have no idea whether the 
function called expects references or not (values).

The only solution I see is to always give references to call_user_func*()

For ex:
-----------------
function MY_call_user_func_array($Func,$Args)
{
  foreach(array_keys($Args) as $i) { $Args[$i] =& $Args[$i]; }//make it a ref
  call_user_func_array($Func,$Args);
}

function test(&$z){  echo "ok : " . $z . "\n";}
$a = 1;
MY_call_user_func_array('test',array($a));
-----------------

And here we are! IT WORKS!
but it I feel like I just learnt how to poo in PHP...

------------------------------------------------------------------------
[2010-09-28 03:13:28] cataphr...@php.net

Yes, this may be confusing. The problem is that the level of indirection added 
means when the function test() is actually called by the implementation of 
call_user_func() via zend_call_function, information about the arguments is 
lost. Use call_user_func_array().

Tests 1 and 3 are basically the same. The manual for call_user_func has a note:

«Note that the parameters for call_user_func() are not passed by reference.»

Since call_user_func doesn't receive its parameters by reference, by the time 
they reach it, it has no way of knowing if the parameters were sent by 
reference or not.

Test 2 is a different matter. But you are actually passing a reference to 
test() because zend_call_function() is nice and when you pass a non-reference 
to a function that expects a reference and the non-reference has refcount 1, it 
converts it into a reference. See

http://lxr.php.net/opengrok/xref/PHP_TRUNK/Zend/zend_execute_API.c#860

Again, this makes sense if you're writing an extension and using 
zend_call_function() and passing it a variable you've created. I don't see how 
this can be fixed, except by adding something like fci->no_separation that 
doesn't create a reference even if the refcount is 1. Not sure if it's worth 
the trouble.

------------------------------------------------------------------------
[2010-09-27 19:31:16] mryaggi at hotmail dot com

Description:
------------
call_user_func now issue a warning in PHP5.3 when giving a value instead of a 
reference.
However, this warning shows up in inappropriate cases.

Test script:
---------------
<?php
//Function to be called via call_user_func
function test(&$z)
{
  echo "ok : " . $z . "\n";
}

// - 1 : With a local variable
//This should work, but...
$a = 1;
call_user_func('test',$a);//Warning: Parameter 1 to test() expected to be a 
reference, value given

// - 2 : Giving a constant
//This should issue a warning but ...
call_user_func('test',2);//works fine. Output "ok : 2"

// - 3 : Base on a parameter
//This should work, but ...
function test3($p=3)
{
call_user_func('test',$p);//Warning: Parameter 1 to test() expected to be a 
reference, value given
}
test3();
?>

Expected result:
----------------
ok : 1
<b>Warning</b>:  Parameter 1 to test() expected to be a reference, value given 
in 
...
ok : 3

Actual result:
--------------
<b>Warning</b>:  Parameter 1 to test() expected to be a reference, value given 
in 
...
ok : 2
<br />
<b>Warning</b>:  Parameter 1 to test() expected to be a reference, value given 
in 
...


------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=52937&edit=1

Reply via email to