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

 ID:                 52937
 Updated by:         cataphr...@php.net
 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

 New Comment:

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.


Previous Comments:
------------------------------------------------------------------------
[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 http://bugs.php.net/bug.php?id=52937&edit=1

Reply via email to