3

最初我以为这将是小菜一碟..不适合我..

如果项目不在 ArrayObject 中,我正在尝试扩展 offsetGet() 函数以返回 null。到目前为止,我似乎无法让它在没有错误的情况下正常工作。

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 的重载元素的间接修改在 -- on line -- 中没有影响

4

2 回答 2

2

简短的回答:这是offsetGet()ArrayObject.

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

作为赋值的一部分,ArrayObject::offsetGet('something')被调用并且返回值期望返回一个引用;问题是,尽管定义了&offsetGet(),但它实际上并没有返回引用。

真正返回的是一个临时变量,因此通知是正确的,断言对该变量所做的任何更改都不会反映在最终数组中。

顺便说一句,如果您实施,就不会发生这种情况ArrayAccess;当然,你不会得到所有附带的方法ArrayObject:(

更新

这个报告看来,HHVM 表现出正确的行为,PHP 7 不会生成任何通知(但在分配期间有错误的行为)。

于 2015-05-28T09:00:47.743 回答
1

我能够使 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];
    }
}
于 2015-05-28T16:17:29.503 回答