свойства только для чтения в PHP? - PullRequest
11 голосов
/ 30 августа 2010

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

echo $objObject->arrArray[0];

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

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

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

Ответы [ 4 ]

25 голосов
/ 30 августа 2010

Хорошо, вопрос в том, где вы хотите запретить писать?

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

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);
4 голосов
/ 30 августа 2010

Если определено, магические функции __get() и __set() будут вызываться при каждом обращении к несуществующему или частному свойству.Это можно использовать для создания методов «get» и «set» для частных свойств, например, сделать их доступными только для чтения или манипулировать данными, когда они хранятся или извлекаются в нем.1006 *

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

3 голосов
/ 30 августа 2010

Если вы используете PHP 5+, вы можете сделать это с помощью методов __set () и __ get () .

Вы должны определить, как они работают, но должны это сделать.

Изменить пример можно следующим образом.

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

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

0 голосов
/ 30 августа 2010

в классе, сделайте это:

private $array;

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

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

$obj->set_array($new_array);
...