4

我编写了实现 ArrayAccess 接口的简单 PHP 类:

class MyArray implements ArrayAccess
{
    public $value;

    public function __construct($value = null)
    {
        $this->value = $value;
    }

    public function &offsetGet($offset)
    {
        var_dump(__METHOD__);

        if (!isset($this->value[$offset])) {
            throw new Exception('Undefined index: ' . $offset);
        }

        return $this->value[$offset];
    }

    public function offsetExists($offset)
    {
        var_dump(__METHOD__);

        return isset($this->value[$offset]);
    }

    public function offsetSet($offset, $value)
    {
        var_dump(__METHOD__);

        $this->value[$offset] = $value;
    }

    public function offsetUnset($offset)
    {
        var_dump(__METHOD__);

        $this->value[$offset] = null;
    }
}

它在 PHP 7 中正常工作,但在 PHP 5.6 和 HHVM 中出现问题。

如果我isset()在未定义的索引上调用函数,PHP 将调用offsetGet()而不是offsetExists()会引起Undefined index注意。

在 PHP 7 中,它offsetGet()仅在offsetExists()返回时调用true,因此没有错误。

我认为这与PHP bug 62059有关。

该代码在 3V4L 可用,因此您可以看到问题所在。如果索引未定义,我添加了更多调试调用并抛出异常,因为 3V4L 中未显示通知: https ://3v4l.org/7C2Fs

不应该有任何通知,否则 PHPUnit 测试将失败。我该如何解决这个错误?

4

2 回答 2

0

看起来这是旧版本的 PHP 和 HHVM 中的一个 PHP 错误。由于不再支持 PHP 5.6,因此不会修复此错误。

快速修复是添加额外的签入方法offsetGet()null在 index 未定义时返回:

class MyArray implements ArrayAccess
{
    public $value;

    public function __construct($value = null)
    {
        $this->value = $value;
    }

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

        return $this->value[$offset];
    }

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

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

    public function offsetUnset($offset)
    {
        $this->value[$offset] = null;
    }
}

请参阅3V4L中的代码和zerkms的注释(firstsecondthird)。

于 2018-08-06T08:51:22.450 回答
-1

我不确定我是否理解你的问题,但也许你可以试试

public function __construct($value =[]){
    $this->value = $value;
}

代替:

public function __construct($value = null){
$this->value = $value;
}
于 2018-08-05T20:29:36.303 回答