I\'ve been reading around on SO, and elsewhere, however I can\'t seem to find anything conclusive.
Is there any way to effectively carry references through this call
I'm answering this myself with a step-by-step reproduction of the issue, which demonstrates that it is likely not possible to achieve the desired functionality.
Our test function is fairly straightforward, and is as follows:
function testFunction(&$argument)
{
$argument++;
}
If we call the function directly, it, of course, behaves as expected:
$value = 1;
testFunction($value);
var_dump($value); // int(2)
If we call the function using call_user_func_array:
call_user_func_array('testFunction', [$value]);
var_dump($value); // int(1)
The value remains at 1, because $value was not passed by reference. We can force this:
call_user_func_array('testFunction', [&$value]);
var_dump($value); // int(2)
Which again works as calling the function directly.
Now, we introduce the class, using __callStatic:
class TestClass
{
public static function __callStatic($name, $argumentArray)
{
return call_user_func_array($name, $argumentArray);
}
}
If we call the function by forwarding it through __callStatic:
TestClass::testFunction($value);
var_dump($value); // int(1)
The value remains at 1, and we also get a warning:
Warning: Parameter 1 to testFunction() expected to be a reference, value given
Which verifies that $argumentArray passed into __callStatic does not contain references. That makes perfect sense, as PHP doesn't know the arguments are intended to be accepted by reference in __callStatic, nor that we are forwarding the arguments on.
If we change __callStatic to accept the array by reference, in an attempt to force the desired behaviour:
public static function __callStatic($name, &$argumentArray)
{
return call_user_func_array($name, $argumentArray);
}
Uh oh! Spaghetti-O's!
Fatal error: Method TestClass::__callstatic() cannot take arguments by reference
Can't do that; besides, that's supported by the documentation anyway:
Note:
None of the arguments of these magic methods can be passed by reference.
Despite not being able to declare __callStatic to accept by reference, if we use call_user_func_array (which would be rather awkward and self-defeating in practice) to forward references through __callStatic:
call_user_func_array(['TestClass', 'testFunction'], [&$value]);
var_dump($value); // int(2)
It once again works.