Проблема с расширением функции ArrayObject :: offsetGet () для возврата значения null, если элемент не находится в массиве

Первоначально я думал, что это будет кусок пирога .. не для меня ..

Я пытаюсь расширить функцию offsetGet (), чтобы она возвращала ноль, если элемент отсутствует в ArrayObject. Пока я не могу заставить его работать без ошибок.

php -v: 5.3.29

Что я делаю неправильно? Ниже мой код и ошибка:

Мой расширенный класс ArrayObject:

class IssetArray extends \ArrayObject {

public function &offsetGet($offset) {
$var = $this->offsetExists($offset) ? parent::offsetGet($offset) : null;
return $var;
}
}

Вот как я это называю:

$array = new \IssetArray();

$array['item'] = 123;
var_dump($array['item']);

var_dump($array['something']['noItem']);

$array['something']['foo'] = 'bar';
var_dump($array['something']['foo']);

$normalArrayObject = new \ArrayObject();
$normalArrayObject['something']['foo'] = 'bar';
var_dump($normalArrayObject['something']['foo']);
var_dump($normalArrayObject['something']['noItem']);

Выходы:

int(123)
NULL
Notice: Indirect modification of overloaded element of \IssetArray has no effect in -- on line --
NULL
string(3) "bar"Notice: Undefined index: noItem in -- on line --
NULL

Что я делаю неправильно?? Если я вызываю обычный ArrayObject, я не получаю косвенную ошибку модификации. Я в таком замешательстве.

Любая помощь будет замечательной. Я гуглил и гуглил без удачи.

Обновить
————

При попытке сделать то же самое с ArrayAccess я сталкиваюсь с той же проблемой. Как я могу обойти это с ArrayAccess?

Моя реализация:

class IssetArray implements \ArrayAccess {

private $container = array();

public function __construct() {}

public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}

public function offsetExists($offset) {
return isset($this->container[$offset]);
}

public function offsetUnset($offset) {
unset($this->container[$offset]);
}

public function &offsetGet($offset) {
$var = isset($this->container[$offset]) ? $this->container[$offset] : null;

return $var;
}
}

Это приводит к той же самой проблеме, которую я вижу с ArrayObject. Примечание: косвенное изменение перегруженного элемента \ IssetArray не оказывает никакого влияния на

3

Решение

Короткий ответ: это неприятный побочный эффект перегрузки offsetGet() метод из ArrayObject,

$array['something']['foo'] = 'bar';

Как часть задания, ArrayObject::offsetGet('something') вызывается и ожидается, что возвращаемое значение вернет ссылку; проблема в том, что, несмотря на определение &offsetGet(), это на самом деле не возвращает ссылку.

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

Кстати, это не произойдет, если вы реализуете ArrayAccess вместо; конечно, вы не получите все методы, которые идут с ArrayObject или 🙁

Обновить

Кажется из этот отчет что HHVM демонстрирует правильное поведение, а PHP 7 не будет генерировать никаких уведомлений (но имеет неправильное поведение во время назначения).

2

Другие решения

Мне удалось заставить приведенную ниже реализацию ArrayAccess работать идеально для моих нужд. Надеюсь, это поможет всем, у кого проблемы такого же типа, как у меня.

Спасибо @Jack за помощь в правильном направлении!

class IssetArray implements \ArrayAccess {

private $container = array();

public function __construct() {}

public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}

public function offsetExists($offset) {
return isset($this->container[$offset]);
}

public function offsetUnset($offset) {
unset($this->container[$offset]);
}

public function &offsetGet($offset) {
if(!isset($this->container[$offset])) {
$this->container[$offset] = null;
}

return $this->container[$offset];
}
}
1

По вопросам рекламы [email protected]