1

示例 php 代码:

class TestArrayObject extends ArrayObject {
    function offsetSet($index,$val){
        echo $index.':'.$val.PHP_EOL;
    }
}

$s = new TestArrayObject();

//test 1
$s['a'] = 'value';//calls offsetSet
//test 2
$s['b']['c'] = 'value';//does not call offsetSet, why?

var_dump($s);

为什么 test 2 不调用 offsetSet 方法?

4

3 回答 3

2

ArrayObject是一大块魔法,因此我不建议使用它,或者更糟糕的是 - 扩展它。

ArrayObject但是您的实际问题与它本身无关。您遇到的是$s['b']['c'] = ...;所谓的偏移量间接修改。'b'PHP 为其执行的代码大致如下所示:

$offset =& $s['b'];
$offset['c'] = ...;

如您所见,偏移量'b'永远不会直接写入。相反,它是通过引用获取的,并且引用被修改。这就是为什么offsetGet会被调用,而不是offsetSet.

于 2011-11-20T10:03:39.237 回答
0

对于多维数组,请参阅此处的用户贡献注释

于 2011-11-20T10:11:06.113 回答
0

这是一种“陷阱”,因为我认为预期的行为将与 OP 中所述的问题一样。

此外,将 ArrayObject 作为 Object 或 Array 访问时,行为并不一致。

例子:

$foo['b']['c'] = 'value'; // no warning
var_dump($foo);

$bar->b->c = 'value'; // triggers warning
var_dump($bar);

我自己的扩展 ArrayObject 的类也遇到了同样的问题。我无法解决这个问题,但设法通过实施一种我用来链接属性创建的新方法来解决它。

class Arraylist extends ArrayObject
{
    public function set($key, $value = null)
    {
        if (!is_null($value)) {
            $val = new ArrayList((array) $value);
        } else {
            $val = new ArrayList();
        }       
        $this->offsetSet($key, $val);
        return $this->offsetGet($key);
    }

    public function offsetSet($index,$val){
        echo $index.':'.$val.PHP_EOL;
        parent::offsetSet($index, $val);
    }
}

使用 OP 示例:

代码:

$s = new ArrayList();
$s->set('a', 'value');
$s->set('b')->set('c', 'another value');
var_dump($s);

输出:

0:value
a:ArrayList
0:value
b:ArrayList
0:another value
c:ArrayList
0:another value

class ArrayList#5 (2) {
  public $a =>
  class ArrayList#7 (1) {
        string(5) "value"
  }
  public $b =>
  class ArrayList#8 (1) {
    public $c =>
    class ArrayList#9 (1) {
            string(13) "another value"
    }
  }
}
于 2012-12-30T17:14:53.423 回答