Edit report at http://bugs.php.net/bug.php?id=52937&edit=1
ID: 52937 Comment by: mryaggi at hotmail 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 New Comment: 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? Previous Comments: ------------------------------------------------------------------------ [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 http://bugs.php.net/bug.php?id=52937&edit=1