Я прочитал много прошлых вопросов о ArrayAccess
PHP интерфейс и его метод offsetGet
который может вернуть ссылку. У меня есть простой класс, реализующий этот интерфейс, который оборачивает переменную типа array
, offsetGet
метод возвращает ссылку, однако я получаю сообщение об ошибке Only variable references should be returned by reference
, Зачем?
class My_Class implements ArrayAccess {
private $data = array();
...
public function &offsetGet($offset) {
return isset( $this->data[ $offset ] ) ? $this->data[ $offset ] : null;
}
...
}
Я хотел бы иметь возможность использовать многомерные массивы с этим классом:
$myclass = new My_Class();
$myclass['test'] = array();
$myclass['test']['test2'] = array();
$myclass['test']['test2'][] = 'my string';
Я думаю, это потому, что вы возвращаете результат выражения, а не переменную.
Попробуйте написать оператор if и вернуть фактическую переменную.
Метод ‘&offsetGet ‘возвращает ссылку (указатель) на переменную.
Вам нужно либо изменить сигнатуру метода из ‘&offsetGet ‘to’ offsetGet ‘или используйте переменную для хранения возвращаемого значения.
// modify method signiture
public function offsetGet($offset) {
return isset( $this->data[ $offset ] ) ? $this->data[ $offset ] : null;
}
// or use a variable to hold the return value.
public function &offsetGet($offset) {
$returnValue = isset( $this->data[ $offset ] ) ? $this->data[ $offset ] : null;
return $returnValue;
}
В этом коде:
public function &offsetGet($offset) {
$returnValue = isset( $this->data[ $offset ] ) ? $this->data[ $offset ] : null;
return $returnValue;
}
$returnValue
является копией $this->data[$offset]
не ссылка.
Вы должны сами сделать ссылку, и для этого вы должны заменить троичный оператор оператором if:
public function &offsetGet($offset) {
if (isset($this->data[$offset]) {
$returnValue &= $this->data[$offset]; // note the &=
}
else {
$returnValue = null;
}
return $returnValue;
}
должен сделать свое дело.
Для несуществующего случая я бы предпочел выдать исключение, подобное тому, которое вы получили при запросе несуществующего ключа массива.
Поскольку возвращаемое вами значение не будет ссылочным,
$myclass['non-existing']['test2'] = array();
предположительно бросит indirect overloaded modification
ошибка и поэтому должна быть запрещена.