有没有办法在PHP中创建对象的只读属性?我有一个带有几个数组的对象。我想像通常的数组一样访问它们
echo $objObject->arrArray[0];
但是我不希望能够在构造之后写入这些数组。感觉就像构建局部变量的PITA一样:
$arrArray = $objObject->getArray1();
echo $arrArray[0];
无论如何,虽然它将数组保持在对象原始状态,但它并不妨碍我重写本地数组变量。
答案 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
...
或者,你可以简单地扩展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
答案 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);