Расширенный ArrayObject PHP не работает должным образом - PullRequest
2 голосов
/ 27 февраля 2010

Я пытаюсь расширить SPL ArrayObject, но наткнулся на небольшую загадку. Используя неизмененный ArrayObject, этот код работает:

$a = new ArrayObject();
$a[1][2] = 'abc';
print_r($a);

получая этот вывод:

ArrayObject Object
(
    [storage:ArrayObject:private] => Array
        (
            [1] => Array
                (
                    [2] => abc
                )

        )
)

Однако, если я расширяю ArrayObject и перегружаю метод offsetGet

class ExtendedArray extends ArrayObject {
    function offsetGet($i) {
        return parent::offsetGet($i);
    }
}

$a = new ExtendedArray();
$a[1][2] = 'abc';
print_r($a);

затем происходит сбой так:

ExtendedArray Object
(
    [storage:ArrayObject:private] => Array
        (
        )

)

Что нужно, чтобы мой расширенный класс работал с многомерными массивами?

1 Ответ

1 голос
/ 27 февраля 2010

Для меня фрагмент # 1 скорее разбит, а не № 2. Вы получаете доступ к элементу, который не существует, и код # 2 дает вам именно то, что можно ожидать: предупреждение. Причина, по которой # 1 вроде "работает", заключается в причуде или двух причудах php. Во-первых, когда вы применяете оператор [] = для нуля, этот нуль «волшебным образом» превращается в массив - без единого слова предупреждения от интерпретатора.

$a = null;
$a[1] = 'foo'; // "works"
print_r($a); 

Во-вторых, это (умышленно или нет) не относится к пустым значениям, возвращаемым из __get или offsetGet.

class foo {
    function __get($s) { return null; }
}

$a = new foo;
$a->x[1] = 'foo'; // error
print_r($a);  

в сообщении об ошибке написано «Косвенное изменение перегруженного свойства», и, что бы это ни значило, это хорошая вещь - вам не разрешено изменять нулевое значение любым способом.

...