Podczas próby zmiany, wyrzuć wyjątek.Jak zaimplementować zmienną składową tylko do odczytu w PHP?
Odpowiedz
Przypuszczam rozwiązanie, dla właściwości klasy, byłoby:
- nie określają właściwość o nazwie, która Cię interesuje
- korzystania z magiczną
__get
sposób aby uzyskać dostęp do nieruchomości, używając "fałszywa" nazwa - definiuje metodę
__set
, więc zgłasza wyjątek podczas próby ustawienia tej właściwości. - Aby uzyskać więcej informacji na temat metod magicznych, patrz: Overloading.
Dla zmiennych, nie sądzę, że możliwe jest, aby mieć zmienną tylko do odczytu, dla której PHP będzie zgłaszać wyjątek, gdy próbujesz pisać do niego.
Na przykład, rozważmy tę małą klasę:
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
}
}
}
Instanciating klasę i próbuje odczytać właściwość:
$a = new MyClass();
echo $a->myVar . '<br />';
będzie Ci oczekiwany wynik:
test
Podczas próby zapisu do właściwego ty:
$a->myVar = 10;
będzie Ci wyjątek:
Exception: not allowed : myVar in /.../temp.php on line 19
class test {
const CANT_CHANGE_ME = 1;
}
i przekazać ją jako test::CANT_CHANGE_ME
Jak rzucisz niestandardowy wyjątek? – user198729
nie wygeneruje wyjątku, ale błąd analizy składni ... –
@ user198729 Dlaczego chcesz * chcesz * dodać niestandardowy wyjątek? – meagar
użyć stałej. Hasło const
wiem, że to jest stare pytanie, ale odpowiedź Pascala naprawdę pomógł mi i chciałem dodać do niej trochę.
__get() uruchamia nie tylko nieistniejące właściwości, ale także "niedostępne", np. chronione. Ułatwia to tworzenie właściwości tylko do odczytu!
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;
}
}
}
Dobra odpowiedź! BTW, do czego służy "__call"? – user198729
'__call' jest wywoływany, gdy próbujesz wywołać metodę, która nie kończy się na klasie (jak' __get' jest wywoływana, gdy próbujesz odczytać właściwość, która nie istnieje w klasie) - zobacz http://fr2.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods –
@Pascal MARTIN, dzięki! Wiem też, że jesteś doświadczonym użytkownikiem symfony/doktryny , możesz rzucić okiem na ten post: http: //stackoverflow.com/questions/2339800/how-can-i-fetch-the-entire-tree-in-a-ingle-query-with-doctrine? – user198729