首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP中的只读属性?

问PHP中的只读属性?
EN

Stack Overflow用户
提问于 2010-08-30 21:28:34
回答 5查看 18.3K关注 0票数 12

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

代码语言:javascript
复制
echo $objObject->arrArray[0];

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

代码语言:javascript
复制
$arrArray = $objObject->getArray1();
echo $arrArray[0];

不管怎样,虽然它保持了对象中数组的原始状态,但它并没有阻止我重写局部数组变量。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-08-30 21:37:55

那么,问题是你想从哪里阻止写作呢?

第一步是将数组设置为受保护的或私有的,以防止来自对象作用域之外的写入:

代码语言:javascript
复制
protected $arrArray = array();

如果来自数组的“外部”,则GETTER会做得很好。以下任一项:

代码语言:javascript
复制
public function getArray() { return $this->arrArray; }

并像这样访问它

代码语言:javascript
复制
$array = $obj->getArray();

或

代码语言:javascript
复制
public function __get($name) {
    return isset($this->$name) ? $this->$name : null;
}

并像这样访问它:

代码语言:javascript
复制
$array = $obj->arrArray;

请注意,它们不返回引用。因此,您不能从对象作用域之外更改原始数组。您可以更改数组本身...

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

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

代码语言:javascript
复制
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成为该对象的实例:

代码语言:javascript
复制
public function __construct(array $input) {
    $this->arrArray = new ImmutableArrayObject($input);
}

它仍然支持大多数类似数组的用法:

代码语言:javascript
复制
count($this->arrArray);
echo $this->arrArray[0];
foreach ($this->arrArray as $key => $value) {}

但是如果你尝试写它,你会得到一个LogicException...

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

代码语言:javascript
复制
$newArray = $this->arrArray->getArrayCopy();
//Edit array here
$this->arrArray = new ImmutableArrayObject($newArray);
票数 25
EN

Stack Overflow用户

发布于 2010-08-30 21:33:23

如果已定义,则无论何时访问不存在的属性或私有属性,都将调用魔术函数__get()和__set()。这可用于为私有属性创建"get“和"set”方法,例如,将它们设为只读,或者在其中存储或检索数据时对其进行操作。

例如:

代码语言:javascript
复制
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。

票数 4
EN

Stack Overflow用户

发布于 2010-08-30 21:31:16

如果你使用的是PHP 5+,你可以用__set()和__get()方法来实现。

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

编辑一个示例如下所示。

代码语言:javascript
复制
class Example {
    private $var;
    public function __get($v) {
        if (is_array($v)) {
            foreach () {
                // handle it here
            }
        } else {
            return $this->$v;
        }
    }
}

这可能不是“最好的”方法,但它会根据您的需要而起作用

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3600777

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档