2011-09-06 4 views
10

Ho bisogno di creare una classe immutabile che è semplicemente un contenitore del campo membro. Voglio che i suoi campi vengano istanziati una volta nel suo costruttore (i valori dovrebbero essere dati come parametri al costruttore). Voglio che i campi siano pubblici ma immutabili. Avrei potuto farlo con Java usando la parola chiave final prima di ogni campo. Come è fatto in PHP?PHP: campi immutabili per i membri pubblici

+3

Questo non è possibile in PHP. – Sjoerd

+0

Perché i campi devono essere pubblici? – Pete171

+0

@ pete171 probabilmente in modo che siano di sola lettura – fbstj

risposta

16

Si dovrebbe usare __set e __get metodi magici e dichiarare che la proprietà come protected o private:

class Example 
{ 
    private $value; 

    public function __construct() 
    { 
     $this->value = "test"; 
    } 

    public function __get($key) 
    { 
     if (property_exists($this, $key)) { 
      return $this->{$key}; 
     } else { 
      return null; // or throw an exception 
     } 
    } 

    public function __set($key, $value) 
    { 
     return; // or throw an exception 
    } 
} 

Utilizzo:

$example = new Example(); 
var_dump($example->value); 
$example->value = "invalid"; 
var_dump($example->value); 

uscita:

string(4) "test" 
string(4) "test" 
2

È possibile utilizzare il metodo magico __set() e generare un'eccezione quando qualcuno tenta di impostare direttamente una proprietà.

class ClassName { 
    public function __set($key, $value) { 
     throw new Exception('Can't modify property directly.'); 
    } 
} 

Tuttavia, questo potrebbe impedire la modifica delle proprietà, indipendentemente dal fatto che siano pubblici o meno.

+0

Dato che le proprietà dovrebbero essere dichiarate private/protetto comunque, che non aggiunge nulla di utile. '__get()' d'altra parte, è ciò che vogliamo. – Mchl

+3

__set() viene eseguito quando si scrivono dati su proprietà inaccessibili. Non funziona con il pubblico – jbrond

2

magic methods

in modo da poter fare meglio - se si dispone di un conteggio Dinamyc di campi

class ClassName { 
     private $fields = array(); 
     // use class : $cl = new ClassName(array('f'=>2,'field_4'=>5,''12)); 
     // echo $cl->field_4; echo $cl->f; 
     public function __construct($data= array()) 
     { 
      if (!is_array($data) || !count($data)) throw new Exception('Not enough args') 
      foreach ($data as $key=>$val) 
      { 
       if (is_numeric($key)) 
       $this->fields['field_'.$key] = $val; 
       else 
       $this->fields[$key] = $val; 
      }  
     } 
      /* in this case you can use this class like $cl = new ClassName(12,14,13,15,12); echo $cl->field_1; 
     public function __construct() 
    { 
      $ata = funcs_get_args(); 

      if (!count($data)) throw new Exception('Not enough args') 
      foreach ($data as $key=>$val) 
      { 
       if (is_numeric($key)) 
       $this->fields['field_'.$key] = $val; 
       else 
       $this->fields[$key] = $val; 
      }  
    } 
    */ 
     public function __get($var) { 
      if (isset($this->fields[$var])) 
       return $this->fields[$var]; 
      return false; 
      //or throw new Exception ('Undeclared property'); 
     } 
    } 
+4

'__set' non viene chiamato per le proprietà pubbliche – sanmai