2013-06-24 10 views
8

In quasi tutte le esercitazioni o risposte su SO, vedo un modo comune per inviare dati da un controller alla vista, la vista classe spesso sembra qualcosa di simile al seguente codice:Passaggio di dati dal controller alla vista in un'app MVC PHP

class View 
{ 
    protected $_file; 
    protected $_data = array(); 

    public function __construct($file) 
    { 
     $this->_file = $file; 
    } 

    public function set($key, $value) 
    { 
     $this->_data[$key] = $value; 
    } 

    public function get($key) 
    { 
     return $this->_data[$key]; 
    } 

    public function output() 
    { 
     if (!file_exists($this->_file)) 
     { 
      throw new Exception("Template " . $this->_file . " doesn't exist."); 
     } 

     extract($this->_data); 
     ob_start(); 
     include($this->_file); 
     $output = ob_get_contents(); 
     ob_end_clean(); 
     echo $output; 
    } 
} 

non capisco il motivo per cui ho bisogno di mettere i dati in un array e quindi chiamare l'estratto ($ this -> _ dati). Perché non mettere direttamente alcune proprietà alla vista dal controller come

$this->_view->title = 'hello world'; 

poi nel mio layout o file di modello che ho potuto solo fare:

echo $this->title; 

risposta

7

È logico raggruppare i dati della vista e differenziarli dalle proprietà della classe di vista interna.

PHP consente di assegnare dinamicamente le proprietà in modo da poter creare un'istanza della classe View e assegnare i dati della vista come proprietà. Personalmente non consiglierei questo però. Che cosa succede se si desidera eseguire un'iterazione sui dati della vista o semplicemente eseguirne il dump per il debug?

Memorizzare i dati della vista in una matrice o contenente oggetto non significa che è necessario utilizzare $this->get('x') per accedervi. Un'opzione è quella di usare PHP5 Property Overloading, che ti permetterà di memorizzare i dati come una matrice, ma avere l'interfaccia $this->x con i dati dal modello.

Esempio:

class View 
{ 
    protected $_data = array(); 
    ... 
    ... 

    public function __get($name) 
    { 
     if (array_key_exists($name, $this->_data)) { 
      return $this->_data[$name]; 
     } 
    } 
} 

Il metodo __get() verrà chiamato se si tenta di accedere a una proprietà che non esiste. Così ora è possibile fare:

$view = new View('home.php'); 
$view->set('title', 'Stackoverflow'); 

Nel modello:

<title><?php echo $this->title; ?></title> 
+1

Grazie mille per il frammento, è fantastico;) – Matthew

1

mia ipotesi che il motivo potrebbe essere semplicemente " meno di battitura "ma che hanno dei bei effetti collaterali:

  • aiuta quando quelli che scrivono i modelli non hanno familiarità con php e in questo modo non c'è bisogno di preoccuparsi della" cosa c forse questo $this-> significa? ".
  • Avere un contenitore separato per le variabili aiuta anche quando ci sono alcune proprietà della vista che dovrebbero essere private per quella classe e gli scrittori di librerie non vogliono esporle agli scrittori di template
  • Impedisce collisioni di nomi con il visualizza le proprietà e le variabili per i modelli.
  • Molto più veloce degli schemi di accesso basati su metodo. Potrebbe non essere così rilevante ora come quando è stato creato ad esempio smarty (funzionante anche con php4).
+0

accordo per il punto 1 e il punto 3. Ma per quanto riguarda il secondo punto, non credo che il contenitore permette di nascondere il privato proprietà di View, puoi ancora fare $ this-> somePrivateProperty perché il file è stato incluso dalla classe View (vedi il codice sopra). – Matthew

+0

Beh, certo, ma almeno in questo modo apparirebbe nettamente distinto dalle variabili "normali" a cui si dovrebbe accedere. – complex857

+0

ok ho capito il tuo punto :) – Matthew

Problemi correlati