Сохранять динамическое количество аргументов по ссылке в объекте, который будет изменен позже - PullRequest
0 голосов
/ 04 декабря 2011

Хорошо, у меня есть уникальная проблема.У меня вызывается функция, и мне нужно, чтобы она работала с тем, как она уже вызывается.Я собрал некоторый код, который показывает как можно ближе к ответу:

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;

Мне нужно $one и $two в конце, чтобы вывести 'somevalue'.Если неясно, мне нужно иметь возможность передавать по ссылке некоторые значения в один метод объекта, а позже иметь отдельный метод объекта, который все еще сможет получить доступ к этим значениям;

Ответы [ 3 ]

1 голос
/ 04 декабря 2011

Вы не можете использовать func_get_args(), потому что, как говорится в руководстве, он не возвращается по ссылке:

Возвращает массив, в котором каждый элемент является копия соответствующего члена списка аргументов текущей пользовательской функции.

Из проверки видно, что func_get_arg() ведет себя так же.

Единственный способпоручить PHP предоставить аргумент по ссылке на функцию с помощью & в списке аргументов функции.Поскольку у вас нет списка аргументов, то, что вы хотите, невозможно.

Это также отвратительный !Передача по ссылке в PHP чревата проблемами , и ее следует избегать.

Однако, если вы хотите изменить свою подпись some_method(), вы можете сделать следующее:

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);

Это будет делать то, что вы хотите.

Также обратите внимание, что передача по ссылке во время вызова (thefunc(&$foo);) устарела и может больше не работать.

1 голос
/ 04 декабря 2011

Я считаю, что это работает:

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

но, как говорили другие, "как он уже вызывается" - это время вызова по ссылке, что устарело

1 голос
/ 04 декабря 2011

Передача по ссылке во время разговора устарела, поскольку результатом является жесткий код. Попробуйте реорганизовать ваше приложение

...