将__set()与Array附加语法一起使用

时间:2012-02-08 21:10:06

标签: php

我有一个神奇的__set($name, $value)方法。在__set()内,是否有一种方法可以检测数字附加短手是否被使用,因此它不会吹走预先存在的值?

class Foo extends ArrayObject {

  protected $bar = array();

  public function __set($name, $value) {
    $this->bar = $value; // I want to handle both replace AND append
  }
}

$foobar = new Foo;
$foobar->bar = array('first element');
$foobar->bar[] = 'new element';

我该如何处理这种情况?

2 个答案:

答案 0 :(得分:4)

您可以使用__get来实现您的目标。

class Foo {

  protected $bar = array();

  public function &__get($name) {
    return $this->$name;
  }

  public function __set($name, $value) {
    $this->$name = $value;
  }
}

$foobar = new Foo;
$foobar->bar = array('first element');
$foobar->bar[] = 'new element';
print_r($foobar->bar);

这是因为[]=操作首先读取属性,然后附加元素。

请注意__get必须返回'by reference'才能生效(至少在PHP 5.4中);如果没有通过引用返回,您会收到有关间接修改的通知。

注意:此时,您可能还可以将其公开,因为效果基本相同。

答案 1 :(得分:1)

由于您正在使用数组访问,因此PHP将在您的bar实例上动态创建名为$foobar的公共成员。实现此目的的一种方法是使用ArrayAccess提供的ArrayObject实现,如下所示:

$foobar = new Foo;
$foobar['baz'] = array('first element');
$foobar['baz'][] = 'new element';

但是,请注意,这将创建一个名为baz的公共属性,将不会使用魔术属性方法(__set()__get()__isset()__unset()