4

First of all, I want to test a function:

private function testMe (array &$output)
{
    $output['a'] = 3; // $$$$ $output gets changes
}

I made a little method to make it public, and call:

public static function makePublicAndCall ($objectInstance, $methodname)
{
    $ref = new ReflectionMethod (get_class($objectInstance), $methodname);
    $ref->setAccessible(true);

    $params = array();
    for ($i = 2+1; $i <= func_num_args(); $i++)
    {
        $params[] = func_get_arg($i-1);
    }
    $result = $ref->invokeArgs ($objectInstance, $params);
    for ($i = 2+1; $i <= func_num_args(); $i++)
    {
        // write back $$$$ here I would need something like "func_get_arg($i-1)"
    }
    return $result;
}

so, using it:

$output = array();
::makePublicAndCall ($object, 'testMe', $output);
// $output OMG output remains the same! It must not be empty but [a] => 3

see the problem? This method has 2 obligatory parameters, and all others are optional (they go to the invoked method itself). But if those parameters are changed, cannot be carried back!

2 Answers 2

2

For PHP 5.6 and above

PHP 5.6 introduced variadic arguments, which can also accept parameters by reference.

function makePublicAndCall ($objectInstance, $methodname, &...$args) { }

now just forward the $args array filled with arguments by ref to $objectInstance->$methodname

function makePublicAndCall ($objectInstance, $methodname, &...$args) {
    $ref = new ReflectionMethod (get_class($objectInstance), $methodname);
    $ref->setAccessible(true);
    return $ref->invokeArgs($objectInstance, $args);
}

makePublicAndCall($object, 'testMe', $output);

For PHP 5.4 and 5.5 versions

No, way, sorry.

For PHP 5.3 and below

Call-time pass by reference still works with these archaic versions, so feel free to use it.

function makePublicAndCall ($objectInstance, $methodname) {
    $ref = new ReflectionMethod (get_class($objectInstance), $methodname);
    $ref->setAccessible(true);
    return $ref->invokeArgs ($objectInstance, $args);
}
@makePublicAndCall($object, 'testMe', &$output); // note the & here...

Also, you don't have to expect a reference in your testMe function, you get an array filled with references, that's enough; you don't need to get an array filled with references by ref to manipulate the references.

Sign up to request clarification or add additional context in comments.

1 Comment

somehow the "For all PHP 5+ versions" version doesnt work... I have to stuck with Php 5.3
0

I solved it, regardless of versions:

public static function makePublicAndCall ($objectInstance, $methodname, array &$params = array())
{
    $ref = new ReflectionMethod (get_class($objectInstance), $methodname);
    $ref->setAccessible(true);

    return $ref->invokeArgs ($objectInstance, array(&$params));
}

calling:

::makePublicAndCall ($object, 'testMe', $output);

EDIT: another solution regardless of version, but I bet you will throw your hat to the floor:

public static function makeStaticMethodPublicAndCall ($className, $method, &$params1 = null, &$params2 = null, &$params3 = null, &$params4 = null)
{
    $className = new ReflectionClass($className);
    $method = $className->getMethod($method);
    $method->setAccessible(true);
    return $method->invokeArgs (null, array(&$params1, &$params2, &$params3, &$params4));
}

    .
    .
    .

::makeStaticMethodPublicAndCall ('MyClass', 'myMethod', $param1, $param2);

2 Comments

That wasn't exactly what you asked. That's passing an array by ref, not variadic arguments...
yeah youre right. First it did solved my problems, but I realized its not good enough

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.