Расширенный PHP ArrayObject Не Работает должным образом
-
23-09-2019 - |
Вопрос
Я пытаюсь расширить 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 довольно неработающий, а не # 2.Вы обращаетесь к элементу, который не существует, и код # 2 дает вам именно то, что можно было бы ожидать:предупреждение.Причина, по которой # 1 вроде как "работает", - это причуда или две причуды php.Во-первых, когда вы применяете оператор []= к null, этот null "волшебным образом" превращается в массив - без единого слова предупреждения от интерпретатора.
$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);
в сообщении об ошибке говорится "Косвенное изменение перегруженного свойства", и, что бы это ни значило, это хорошо - вам не разрешено каким-либо образом изменять значение null.