Matthew
Matthew

Reputation: 15652

Store dynamic number of arguments by reference in object, to be changed later

Ok I've got a unique problem. I have a function being called, and I need this to work with how it's already being called. I've put together some code that shows as close as I can get to the answer:

class some_class {
    private $_some_stuff = array();

    public function some_method()
    {
        $args = func_get_args();
        foreach($args as &$name)
        {
            $this->_some_stuff[] =& $name;
        }
    }

    public function other_method()
    {
        for ($i = 0; $i < count($this->_some_stuff); $i++)
        {
            $this->_some_stuff[$i] = 'somevalue';
        }
    }
}


$some_object = new some_class();
$one = 'firstever';
$two = 'secondever';
$some_object->some_method(&$one, &$two);
$some_object->other_method(&$one, &$two);

echo $one;
echo '<br>...<br>';
echo $two;

I need $one and $two at the end to output 'somevalue'. If it's not clear, I need to be able to pass by reference some values into one method of an object and later have a separate method of the object still be able to access those values;

Upvotes: 0

Views: 71

Answers (3)

newacct
newacct

Reputation: 122449

I believe that this works:

public function some_method()
{
    $backtrace = debug_backtrace();
    $args = $backtrace[0]['args'];
    foreach($args as &$name)
    {
        $this->_some_stuff[] =& $name;
    }
}

but as others have said, "how it's already being called" is call-time pass by reference, which is deprecated

Upvotes: 1

Francis Avila
Francis Avila

Reputation: 31631

You can't use func_get_args() because as the manual says it does not return by reference:

Returns an array in which each element is a copy of the corresponding member of the current user-defined function's argument list.

It appears from testing that func_get_arg() has the same behavior.

The only way to instruct PHP to provide an argument by reference to a function is with the & in the function argument list. Since you don't have an argument list, what you want is impossible.

It's also hideous! Pass-by-reference in PHP is fraught with problems and should be avoided.

However, if you are willing to change your some_method() signature, you can do the following:

class some_class {
    private $_some_stuff = array();

    public function some_method(&$args)  // notice we accept a single arg by reference
    {
        foreach ($args as &$arg) {
            $this->_some_stuff[] =& $arg;
        }
    }

    public function other_method()
    {
        for ($i = 0; $i < count($this->_some_stuff); $i++)
        {
            $this->_some_stuff[$i] = 'somevalue';
        }
    }
}


$some_object = new some_class();
$one = 'firstever';
$two = 'secondever';

// now whenever you call this method, use this EXACT PATTERN:
$args = array(&$one, &$two); // this MUST be its own statement on its own line, and MUST have referenced elements!
$some_object->some_method($args); // CANNOT do $some_object->some_method(array(&$one, &$two)); !!!
$some_object->other_method();
var_dump($some_object);

var_dump($args);
var_dump($one);
var_dump($two);

That will do what you want.

Also note that call-time pass-by-reference (thefunc(&$foo);) is depreciated and may not work anymore.

Upvotes: 1

nonlux
nonlux

Reputation: 31

Call-time pass-by-reference has been deprecated, because the result is a hard code. Try to reorganize your application

Upvotes: 1

Related Questions