Свойства только для чтения в PHP?

Есть ли способ сделать свойство только для чтения объекта в PHP? У меня есть объект с несколькими массивами. Я хочу получить к ним доступ, как обычно, массив

echo $objObject->arrArray[0];

Но я не хочу писать эти массивы после их создания. Похоже, что PITA создает локальную переменную:

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

И в любом случае, хотя он сохраняет массив в объекте нетронутым, он не мешает мне переписывать переменную локального массива.

Ответ 1

Ну, вопрос в том, где вы хотите предотвратить письмо?

Первый шаг - сделать массив защищенным или приватным, чтобы предотвратить запись из области видимости объекта:

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

Ответ 2

Если определено, магические функции __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

См. также справочная страница для перегрузки в PHP.

Ответ 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;
        }
    }
}

Это может быть не "лучший" способ сделать это, но он будет работать в зависимости от того, что вам нужно

Ответ 4

в классе, сделайте следующее:

private $array;

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

то вы просто установите так:

$obj->set_array($new_array);