2010-02-26 14 views

risposta

19

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 
+0

Buona risposta! BTW, a cosa serve "__call"? – user198729

+0

'__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 –

+0

@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

13
class test { 
    const CANT_CHANGE_ME = 1; 
} 

e si riferiscono come test::CANT_CHANGE_ME

+0

Come verrà generata un'eccezione personalizzata? – user198729

+0

non sarà generato un'eccezione, ma un errore di analisi ... –

+3

@ user198729 Perché si vuole * * a un'eccezione personalizzata? – meagar

3

utilizzare una costante. Chiave const

0

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; 
     } 
    } 
} 
Problemi correlati