PHP中的只读属性?

时间:2010-08-30 13:28:34

标签: php oop readonly

有没有办法在PHP中创建对象的只读属性?我有一个带有几个数组的对象。我想像通常的数组一样访问它们

echo $objObject->arrArray[0];

但是我不希望能够在构造之后写入这些数组。感觉就像构建局部变量的PITA一样:

$arrArray = $objObject->getArray1();
echo $arrArray[0];

无论如何,虽然它将数组保持在对象原始状态,但它并不妨碍我重写本地数组变量。

4 个答案:

答案 0 :(得分:25)

嗯,问题是你想在哪里阻止写作?

第一步是使数组受保护或私有以防止从对象范围之外写入:

protected $arrArray = array();

如果来自阵列的“外部”,GETTER会对你没问题。之一:

public function getArray() { return $this->arrArray; }

一样访问它
$array = $obj->getArray();

public function __get($name) {
    return isset($this->$name) ? $this->$name : null;
}

并像访问它一样:

$array = $obj->arrArray;

请注意,它们不会返回引用。因此,您无法从对象范围之外更改原始数组。你可以改变阵列本身......

如果您确实需要一个完全不可变的数组,可以使用ArrayAccess ...

来使用Object

或者,你可以简单地扩展ArrayObject并覆盖所有的写作方法:

class ImmutableArrayObject extends ArrayObject {
    public function append($value) {
        throw new LogicException('Attempting to write to an immutable array');
    }
    public function exchangeArray($input) {
        throw new LogicException('Attempting to write to an immutable array');
    }
    public function offsetSet($index, $newval) {
        throw new LogicException('Attempting to write to an immutable array');
    }
    public function offsetUnset($index) {
        throw new LogicException('Attempting to write to an immutable array');
    }
}

然后,只需将$this->arrArray作为对象的实例:

public function __construct(array $input) {
    $this->arrArray = new ImmutableArrayObject($input);
}

它仍然支持大多数数组,如用法:

count($this->arrArray);
echo $this->arrArray[0];
foreach ($this->arrArray as $key => $value) {}

但如果你试着写信给它,你会得到LogicException ...

哦,但是要意识到如果你需要写它,你需要做的就是(在对象内):

$newArray = $this->arrArray->getArrayCopy();
//Edit array here
$this->arrArray = new ImmutableArrayObject($newArray);

答案 1 :(得分:4)

如果已定义,则只要访问不存在或私有属性,就会调用魔术函数__get()__set()。这可以用于为私有属性创建“get”和“set”方法,例如,在存储或检索数据时将它们设置为只读或操作数据。

例如:

class Foo
{
  private $bar = 0;
  public $baz = 4; // Public properties will not be affected by __get() or __set()
  public function __get($name)
  {
    if($name == 'bar')
      return $this->bar;
    else
      return null;
  }
  public function __set($name, $value)
  {
    // ignore, since Foo::bar is read-only
  }
}

$myobj = new Foo();
echo $foo->bar; // Output is "0"
$foo->bar = 5;
echo $foo->bar; // Output is still "0", since the variable is read-only

另请参阅manual page for overloading in PHP

答案 2 :(得分:3)

如果您使用的是PHP 5+,则可以使用__set()和__get()方法。

你必须定义它们的工作方式,但应该这样做。

编辑示例就像这样。

class Example {
    private $var;
    public function __get($v) {
        if (is_array($v)) {
            foreach () {
                // handle it here
            }
        } else {
            return $this->$v;
        }
    }
}

这可能不是“最好”的做法,但它会根据你的需要而工作

答案 3 :(得分:0)

在课堂上

执行此操作:

private $array;

function set_array($value) {
    $this->array = $value;
}

然后你就这样设置:

$obj->set_array($new_array);