ArrayAccess в PHP - присвоение смещения по ссылке

Сначала цитата из руководства ole' по ArrayAccess::offsetSet():

Эта функция не вызывается в присваиваниях по ссылке и других косвенных изменениях размерности массива, перегруженного ArrayAccess (косвенных в том смысле, что они делаются не путем изменения размерности непосредственно, а путем изменения подразмерности или подсвойства или присвоения размерности массива по ссылке на другую переменную). Вместо этого вызывается ArrayAccess::offsetGet(). Операция будет успешной, только если этот метод вернет значение по ссылке, что возможно только начиная с версии PHP 5.3.4.

Меня это немного смущает. Похоже, это говорит о том, что (начиная с версии 5.3.4) можно определить offsetGet() для возврата по ссылке в реализующем классе, таким образом обрабатывая присваивания по ссылке.

Итак, теперь тестовый фрагмент:

(Не обращайте внимания на отсутствие валидации и isset() проверки)

class Test implements ArrayAccess
{
    protected $data = array();

    public function &offsetGet($key)
    {
        return $this->data[$key];
    }

    public function offsetSet($key, $value)
    {
        $this->data[$key] = $value;
    }

    public function offsetExists($key) { /* ... */ }

    public function offsetUnset($key) { /* ... */ }

}

$test = new Test();

$test['foo'] = 'bar';
$test['foo'] = &$bar; // Fatal error: Cannot assign by reference to
                      // overloaded object in

var_dump($test, $bar);    

Хорошо, это не работает. Тогда к чему относится эта заметка в руководстве?

Причина
Я хотел бы разрешить присваивание по ссылке через оператор массива объекту, реализующему ArrayAccess, как показано в примере. Я исследовал это раньше и не думал, что это возможно, но вернувшись к этому из-за неопределенности, я (повторно) обнаружил это упоминание в руководстве. Теперь я просто в замешательстве.


Update: Когда я нажал Post Your Question, я понял, что это, скорее всего, относится к присвоению по ссылке на другую переменную, например $bar = &$test['foo'];. Если это так, то прошу прощения; хотя знать, как, если это вообще возможно, присвоить по ссылке на перегруженный объект, было бы здорово.


Further elaboration: Все сводится к тому, что я хотел бы иметь следующие псевдонимы методов:

isset($obj[$key]);       // $obj->has_data($key);

$value = $obj[$key];     // $obj->get_data($key);

$obj[$key] = $value;     // $obj->set_data($key, $value);

$obj[$key] = &$variable; // $obj->bind_data($key, $variable);

// also, flipping the operands is a syntactic alternative
$variable = &$obj[$key]; // $obj->bind_data($key, $variable);

unset($obj[$key]);       // $obj->remove_data($key);

Что касается has, get, set и remove, то они без проблем работают с поддерживаемыми методами ArrayAccess. Функциональность связывания - вот где я в растерянности и начинаю приходить к выводу, что ограничения ArrayAccess и PHP просто запрещают это.

16
задан Dan Lugg 3 February 2015 в 21:16
поделиться