Quando si tenta di cambiarlo, lanciare un'eccezione.Come implementare una variabile membro di sola lettura in PHP?
risposta
immagino una soluzione, per le proprietà di classe, sarebbe quello di:
- non definiscono una proprietà con il nome che ti interessa
- utilizzare il metodo magico
__get
per accedere a tale proprietà, utilizzando il Il nome "falso" - definisce il metodo
__set
in modo da generare un'eccezione quando si tenta di impostare tale proprietà. - Vedere Overloading, per ulteriori informazioni sui metodi magici.
Per le variabili, non credo sia possibile avere una variabile di sola lettura per i quali il PHP un'eccezione quando si sta cercando di scrivere.
Ad esempio, si consideri questa piccola classe:
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 la classe e cercando di leggere la proprietà:
$a = new MyClass();
echo $a->myVar . '<br />';
ti porterà i risultati attesi:
test
Durante il tentativo di scrivere sul corretto ty:
$a->myVar = 10;
si arriva un'eccezione:
Exception: not allowed : myVar in /.../temp.php on line 19
class test {
const CANT_CHANGE_ME = 1;
}
e si riferiscono come test::CANT_CHANGE_ME
Come verrà generata un'eccezione personalizzata? – user198729
non sarà generato un'eccezione, ma un errore di analisi ... –
@ user198729 Perché si vuole * * a un'eccezione personalizzata? – meagar
utilizzare una costante. Chiave const
So che questa è una vecchia questione, ma la risposta di Pascal mi ha veramente aiutato e volevo aggiungere ad essa un po '.
__get() attiva non solo proprietà inesistenti, ma anche "inaccessibili", ad es. quelli protetti. Questo rende facile creare proprietà di sola lettura!
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;
}
}
}
Buona risposta! BTW, a cosa serve "__call"? – user198729
'__call' viene chiamata quando si sta cercando di chiamare un metodo che non esce nella classe (come' __get' viene chiamata quando si sta cercando di leggere una proprietà che non esiste nella classe) - vedi http://fr2.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods –
@Pascal MARTIN, grazie! so anche che sei un utente esperto di symfony/doctrine , si può dare un'occhiata a questo post: http: //stackoverflow.com/questions/2339800/how-can-i-fetch-the-entire-tree-in-a-single-query-with-doctrine? – user198729