Как реализовать переменную-член, доступную только для чтения, в PHP?
-
23-09-2019 - |
Вопрос
При попытке изменить его создайте исключение.
Решение
Я полагаю, что решение для свойств класса будет заключаться в следующем:
- не определять свойство с именем, которое вас интересует
- использовать магию
__get
метод доступа к этому свойству, используя «поддельное» имя - определить
__set
метод, поэтому он выдает исключение при попытке установить это свойство. - Видеть Перегрузка, для получения дополнительной информации о магических методах.
Что касается переменных, я не думаю, что возможно иметь переменную, доступную только для чтения, для которой PHP будет генерировать исключение, когда вы пытаетесь записать в нее запись.
Например, рассмотрим этот небольшой класс:
class MyClass {
protected $_data = array(
'myVar' => 'test'
);
public function __get($name) {
if (isset($this->_data[$name])) {
return $this->_data[$name];
} else {
// non-existant property
// => up to you to decide what to do
}
}
public function __set($name, $value) {
if ($name === 'myVar') {
throw new Exception("not allowed : $name");
} else {
// => up to you to decide what to do
}
}
}
Создание экземпляра класса и попытка прочитать свойство:
$a = new MyClass();
echo $a->myVar . '<br />';
Получите ожидаемый результат:
test
При попытке записи в свойство:
$a->myVar = 10;
Получите вам исключение:
Exception: not allowed : myVar in /.../temp.php on line 19
Другие советы
class test {
const CANT_CHANGE_ME = 1;
}
и вы называете это как test::CANT_CHANGE_ME
Используйте константу.Ключевое слово const
Я знаю, что это старый вопрос, но ответ PASCAL мне очень помог, и я хотел немного добавить к нему.
__get() срабатывает не только для несуществующих свойств, но и для «недоступных», напримерзащищенные.Это позволяет легко создавать свойства, доступные только для чтения!
class MyClass {
protected $this;
protected $that;
protected $theOther;
public function __get( $name ) {
if ( isset( $this->$name ) ) {
return $this->$name;
} else {
throw new Exception( "Call to nonexistent '$name' property of MyClass class" );
return false;
}
}
public function __set( $name ) {
if ( isset( $this->$name ) ) {
throw new Exception( "Tried to set nonexistent '$name' property of MyClass class" );
return false;
} else {
throw new Exception( "Tried to set read-only '$name' property of MyClass class" );
return false;
}
}
}
Короткий ответ: вы не можете создать в PHP переменную-член объекта, доступную только для чтения.
Фактически, большинство объектно-ориентированных языков в любом случае считают плохим тоном публичное раскрытие переменных-членов...(C# — большое и уродливое исключение с его конструкциями свойств).
Если вам нужна переменная класса, используйте const
ключевое слово:
class MyClass {
public const myVariable = 'x';
}
Доступ к этой переменной можно получить:
echo MyClass::myVariable;
Эта переменная будет существовать ровно в одной версии независимо от того, сколько разных объектов типа MyClass
вы создаете, и в большинстве объектно-ориентированных сценариев это практически бесполезно.
Однако если вам нужна переменная, доступная только для чтения, которая может иметь разные значения для каждого объекта, вам следует использовать закрытую переменную-член и метод доступа (так называемый геттер):
class MyClass {
private $myVariable;
public function getMyVariable() {
return $this->myVariable;
}
public function __construct($myVar) {
$this->myVariable = $myVar;
}
}
Переменная устанавливается в конструкторе и становится доступной только для чтения из-за отсутствия установщика.Но каждый экземпляр MyClass
может иметь собственное значение для myVariable
.
$a = new MyClass(1);
$b = new MyClass(2);
echo $a->getMyVariable(); // 1
echo $b->getMyVariable(); // 2
$a->setMyVariable(3); // causes an error - the method doesn't exist
$a->myVariable = 3; // also error - the variable is private