PHP ArrayAccess - многомерный массив и offsetGet со ссылкой

Я прочитал много прошлых вопросов о 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';

3 ответа

В этом коде:

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 ошибка и поэтому должна быть запрещена.

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

см. руководство по php -> второе примечание

Метод '&offsetGet' возвращает ссылку (указатель) на переменную.

Вам нужно либо изменить сигнатуру метода с '&offsetGet' на '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;
}
Другие вопросы по тегам