read-only properties in PHP?

孤街醉人 提交于 2019-12-01 14:18:14

问题


Is there a way to make a read-only property of an object in PHP? I have an object with a couple arrays in it. I want to access them as I normally would an array

echo $objObject->arrArray[0];

But I don't want to be able to write to those arrays after they're constructed. It feels like a PITA to construct a local variable:

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

And anyways, while it keeps the array in the object pristine, it doesn't prevent me from re-writing the local array variable.


回答1:


Well, the question is where do you want to prevent writing from?

The first step is making the array protected or private to prevent writing from outside of the object scope:

protected $arrArray = array();

If from "outside" of the array, a GETTER will do you fine. Either:

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

And accessing it like

$array = $obj->getArray();

or

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

And accessing it like:

$array = $obj->arrArray;

Notice that they don't return references. So you cannot change the original array from outside the scope of the object. You can change the array itself...

If you really need a fully immutable array, you could use a Object using ArrayAccess...

Or, you could simply extend ArrayObject and overwrite all of the writing methods:

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');
    }
}

Then, simply make $this->arrArray an instance of the object:

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

It still supports most array like usages:

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

But if you try to write to it, you'll get a LogicException...

Oh, but realize that if you need to write to it, all you need to do (within the object) is do:

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



回答2:


If defined, the magic functions __get() and __set() will be called whenever a non-existing or private property is accessed. This can be used to create "get" and "set" methods for private properties, and for instance make them read-only or manipulate the data when stored or retrieved in it.

For instance:

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

See also the manual page for overloading in PHP.




回答3:


If you're using PHP 5+ you can do it with __set() and __get() methods.

You have to define how they work but should do just this.

Edit an example would be like this.

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

This might not be the "best" way of doing it but it'll work depending on what you need




回答4:


in the class, do this:

private $array;

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

then you just set like this:

$obj->set_array($new_array);


来源:https://stackoverflow.com/questions/3600777/read-only-properties-in-php

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!