Во-первых, цитата из руководства 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
, как показывает пример. Я исследовал это раньше, и я не думал, что это возможно, но, вернувшись к этому из-за неопределенности, я (повторно) обнаружил это упоминание в руководстве. Теперь я просто смущен.
Обновить. Когда я нажал Post Your Question, я понял, что это скорее всего относится к присваиванию ссылочной переменной другой, например $bar = &$test['foo'];
. Если это дело, то извиняйтесь; хотя зная, как, если это вообще возможно, назначить по ссылке на перегруженный объект, было бы здорово.
Дальнейшая разработка. К чему все это сводится, хочу, чтобы у меня были следующие псевдонимы методов:
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
go, это не проблема с поддерживаемыми методами ArrayAccess
. Функциональность привязки - это то место, где я нахожусь в убытке, и я начинаю считать, что ограничения ArrayAccess и PHP просто запрещают это.