通过 ArrayAccess 访问多维数组

accessing multi dimensional arrays via ArrayAccess

假设我有以下代码:

<?php

class test implements ArrayAccess {
    var $var;

    function __construct()
    {
        $this->var = array(
            'a' => array('b' => 'c'),
            'd' => array('e' => 'f'),
            'g' => array('h' => 'i')
        );
    }

    function offsetExists($offset)
    {
        return isset($this->var);
    }

    function offsetGet($offset)
    {
        return isset($this->var[$offset]) ? $this->var[$offset] : null;
    }

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

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

$test = new test();
$test['a']['b'] = 'zzz';

print_r($test->var);

我想要的是显示如下内容:

Array
(
    [a] => Array
        (
            [b] => zzz
        )

    [d] => Array
        (
            [e] => f
        )

    [g] => Array
        (
            [h] => i
        )

)

实际显示的是这样的:

Array
(
    [a] => Array
        (
            [b] => c
        )

    [d] => Array
        (
            [e] => f
        )

    [g] => Array
        (
            [h] => i
        )

)

即。 $test['a']['b']不变。

知道如何使用该语法使其可变吗?我可以将 $test['a'] 分配给一个变量,然后执行 $temp['b'] = 'zzz'; 然后执行 $test['a'] = $temp; 但是 idk - 这似乎过分了。

您正在打印 class 中的数组。试试这个

$test = new test();
$data = $test -> var;
$data['a']['b']= 'ssss';

print_r($data) ;

希望对您有所帮助。

问题是 offsetGet return 是一个按值排列的数组,即内部值的副本。 $test['a']['b'] = 'zzz' 对此副本进行操作,return 编辑者 $test['a']

但您可以将 offsetGet return 改为参考:

    function &offsetGet($offset)
    {
        $null = null;
        if (isset($this->var[$offset])) {
            return $this->var[$offset];
        }
        return $null;
    }

请注意,我还必须修改方法体,以便 return 后面始终跟有变量,而不是表达式。

演示:

https://3v4l.org/4jGMN

Output for 5.4.7 - 7.0.0rc2, hhvm-3.6.1 - 3.9.0

Array
(
    [a] => Array
        (
            [b] => zzz
        )

    [d] => Array
        (
            [e] => f
        )

    [g] => Array
        (
            [h] => i
        )

)

更新

您甚至可以将其简化为:

function &offsetGet($offset)
{
    return $this->v[$offset];
}

因为如果您 return 通过引用引用不存在的变量,它们将被隐式创建。这样,您就可以像这样创建新的嵌套元素:

$test['new']['nested'] = 'xxx';

演示:https://3v4l.org/OSvuA