cambraca
cambraca

Reputation: 27835

Variable-length by-ref argument lists in functions

In PHP you can do this:

function something() {
  foreach (func_get_args() as $arg)
    echo $arg;
}
something(1, 3); //echoes "13"

This works fine for arguments passed by value, but what if I want them to be passed by reference? like this:

function something_else() {
  foreach (func_get_args() as $arg)
    $arg *= 2;
}
$a = 1;
$b = 3;
something_else($a, $b);
echo $a . $b; //should echo "26", but returns "13" when I try it

Is this possible in PHP?

Upvotes: 4

Views: 90

Answers (3)

newacct
newacct

Reputation: 122449

You can do it this way but it uses call-time pass by reference which is deprecated in PHP 5.3:

function something_else() {
    $backtrace = debug_backtrace();
    foreach($backtrace[0]['args'] as &$arg)
    $arg *= 2;
}
$a = 1;
$b = 3;
something_else(&$a, &$b);
echo $a . $b;

Upvotes: 1

Martin Dimitrov
Martin Dimitrov

Reputation: 4956

No. You cannot. The declaration of a prameter passed by ref is explicit as function something(&$arg1, &$arg2). If you don't know the number of parameters at compile time, you can do something like this:

function something_else($args) {
      foreach ($args as $arg)
        $GLOBALS[$arg] *= 2;
}
$a = 1;
$b = 3;
something_else(array('a', 'b'));
echo $a . $b; //returns "26"

Basically the code passes to the function the names of the params the function will modify. $GLOBALS holds references to all defined variables in the global scope of the script. This means if the call is from another function it will not work:

function something_else($args) {
      foreach ($args as $arg)
        $GLOBALS[$arg] *= 2;
}

function other_function(){
    $a = 1;
    $b = 3;
    something_else(array('a', 'b'));
    echo $a . $b; //returns "13"
}
other_function();

triggers notices undefined indexes a and b. So another approach is to create an array with references to the variables the function will modify as:

function something_else($args) {
      foreach ($args as &$arg)
        $arg *= 2;
}

function other_fucntion(){
    $a = 1;
    $b = 3;
    something_else(array(&$a, &$b));
    echo $a . $b; //returns "26"
}
other_fucntion();

Note the & on the foreach line. It is needed so not to create a new variable iterating over the array. PHP > 5 needed for this feature.

Upvotes: 1

salathe
salathe

Reputation: 51950

The question seems horrible, but lets humour you. Below is a horrible hack, but you could send across a single argument which contains the items that you want to work with.

function something_else($args) {
    foreach ($args as &$arg) {
        $arg *= 2;
    }
}
$a = 1;
$b = 3;
something_else(array(&$a, &$b));
echo $a . $b; // 26

Upvotes: 2

Related Questions