PHP中的只读属性?

PHP中的只读属性?,php,oop,readonly,Php,Oop,Readonly,有没有办法在PHP中创建对象的只读属性?我有一个包含两个数组的对象。我想像通常使用数组一样访问它们 echo $objObject->arrArray[0]; 但我不想在这些数组构建之后再写入它们。构造局部变量感觉像PITA: $arrArray = $objObject->getArray1(); echo $arrArray[0]; 无论如何,虽然它保持了对象中的数组的原始状态,但它并不阻止我重新编写局部数组变量。如果您使用的是PHP5+,则可以使用_set()和方法 你必须

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

echo $objObject->arrArray[0];
但我不想在这些数组构建之后再写入它们。构造局部变量感觉像PITA:

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

无论如何,虽然它保持了对象中的数组的原始状态,但它并不阻止我重新编写局部数组变量。

如果您使用的是PHP5+,则可以使用_set()和方法

你必须定义它们是如何工作的,但应该这样做

编辑一个这样的例子

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

这可能不是“最好”的方法,但它会根据您的需要而起作用。如果定义了,则每当访问不存在的或私有的属性时,都会调用神奇的函数
\uuuu get()
\uu 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

另请参见。

问题是,您希望从何处防止书写

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

protected $arrArray = array();
如果从数组的“外部”,则使用GETTER会很好。要么:

public function getArray() { return $this->arrArray; }
并且像这样访问它

$array = $obj->getArray();

并以如下方式访问它:

$array = $obj->arrArray;
请注意,它们不返回引用。因此,不能在对象范围之外更改原始数组。您可以更改阵列本身

如果你真的需要一个完全不可变的数组,你可以使用一个对象使用

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

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->arraray
作为对象的实例:

public function __construct(array $input) {
    $this->arrArray = new ImmutableArrayObject($input);
}
它仍然支持大多数类似阵列的用法:

count($this->arrArray);
echo $this->arrArray[0];
foreach ($this->arrArray as $key => $value) {}
但是如果您尝试写入它,您将得到一个
逻辑异常

哦,但是要意识到,如果你需要对它进行写入,你所需要做的(在对象中)就是:

在课堂上,执行以下操作:

private $array;

function set_array($value) {
    $this->array = $value;
}
然后你就这样设置:

$obj->set_array($new_array);

老板:“我以为你说你完成了你的算法”客户:“我完成了,老板,有什么问题吗”老板:“它不起作用”客户:“它起作用取决于你需要什么”@Chris客户为什么要接受老板的命令?Lol。如果不允许设置特定变量,我建议在
set
中抛出异常。原因是,否则,当一个新人需要做某件事,而这件事不起作用时,可能会让人很困惑。“但我将该数组设置为包含此变量。赋值成功,那么为什么*#@$不起作用?”…如果我想让我的不可变数组在创建时加载数据,我会覆盖_构造函数,调用父构造函数,但我如何设置对象包含的内容?回答得很好!但请注意,数组可以包含对象:每个对象都作为引用返回并可以更改,即使使用不可变类也是如此:
$a=newImmutableArrayObject((object)['foo'=>bar'])$b=a美元[0]$b->foo=‘已更改’
private $array;

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