MVC Visualizza domanda

3

Nella mia pagina web PHP (index.php), ho un semplice script che chiama una classe "page" e poi ne costruisce la pagina.

Index.php esegue i metodi all'interno di un'istanza della classe 'page', come ad esempio "add_to_body (" bla bla bla ")". Può quindi chiamare un metodo "build ()", in cui la classe della pagina restituirà una stringa con l'input dell'utente e alcuni altri elementi HTML pre-aggiunti in, che index.php può echo. Essenzialmente la classe di pagina è un modello di sorta.

Sto provando ad avere una specie di gerarchia MVC qui (sono uno studente che impara a programmare le "migliori pratiche" nel mio tempo libero), la mia domanda è: sarebbe "index.php" essere una visione? Oppure, l'istanza della classe di pagine sarebbe la vista (mentre costruisce la pagina, ma in realtà non la mostra, restituisce una stringa), oppure: la classe 'page' sarebbe un controller?

Inoltre, una vista 'permessa' di dialogare con (ad esempio: ottenere dati da) un controller (ad esempio: chiamando un metodo posseduto dal controller)?

Mille grazie per il tuo aiuto!

    
posta BnMcG 10.05.2013 - 23:45
fonte

3 risposte

3

generalmente l'idea con una "vista" è che è il più "muto" possibile. ha il minimo di codice per visualizzare la pagina. il "Modello" è tipicamente i metodi che comunicano con un database, convalidando i dati, creando e restituendo strutture dati - oggetto, array, ecc. il "Controller" si trova nel mezzo della Vista e del Modello.

così come se hai un modulo di contatto - il controllore dice a un modello di convalidare i dati del modulo e aggiungerlo a un database. se il modello ritorna con "validazione fallita" - dice il controllore - mostra di nuovo questo modulo - e passa i dati rilevanti alla vista pertinente. oppure se il modello dice "nuovo contatto aggiunto" - dice il controllore - mostra la pagina di ringraziamento.

quando sei a tuo agio suggerirei di dare un'occhiata a un framework php di base come codeigniter. può rendere più facile vedere come le parti MVC sono in relazione tra loro.

Risposta

: la vista dovrebbe essere un file separato e ci dovrebbero essere file di visualizzazione separati per esigenze diverse. rimuovere la maggior logica possibile dai file di visualizzazione. questo significa che finirai per avere più file, ma altrimenti il tuo file di visualizzazione "Conosce" troppo la tua applicazione. l'esempio classico sta avendo qualche tipo di controllo in un file di visualizzazione se la persona che lo guarda ha i privilegi di amministratore. il file di visualizzazione non dovrebbe saperlo. basta creare file separati.

in una piccola applicazione è possibile combinare controller e modello nello stesso file. e questo è un buon modo per iniziare: costruisci la tua applicazione e poi, man mano che i metodi diventano chiari, rifatti i metodi dal controller, nei tuoi modelli.

Mi affretto ad aggiungere che dovresti imparare un framework php come codeigniter, anche se solo per vedere esempi di MVC. il framework ti dà un buon punto di partenza e puoi anche guardare ad altre applicazioni per le persone.

    
risposta data 11.05.2013 - 00:20
fonte
2

Esistono diversi approcci a MVC. Un'architettura MVC consiste sempre di almeno quattro parti.

  1. Dispatcher . Decide quale controller è utilizzato.
  2. Regolatore . Prende decisioni su modelli e viste.
  3. Modello . Gestisce i dati.
  4. Visualizza . Genera l'output.

I due principali approcci a MVC differiscono nel luogo, dove entra in gioco la logica aziendale. Uno inserisce nel modello ( Regolatore sottile / Fat Model ), il altro nel controller ( Fat Controller / Thin Model ).

Nell'attuale implementazione, index.php è Dispatcher e sembra contenere anche il Controller . La classe Page è la Visualizza . Dalla tua descrizione non posso dire, dove è il modello ; dovrebbe essere in index.php , ma probabilmente ci sono parti di esso nella classe Page . Ci vuole un po 'di esperienza per creare una separazione appropriata.

    
risposta data 13.05.2013 - 12:37
fonte
0

Also, is a view 'allowed' to talk to (eg: get data from) a controller (for example: by calling a method that controller owns)?

La best practice è no, ma a un controllore è consentito passare un dato alla vista. Scopri i motori di template come Moustache .

I'm trying to have some kind of MVC hierarchy here (I'm a student learning about programming 'best practices' in my own time), my question is: would 'index.php' be a view? Or, would the instance of the page class be the view (as it constructs the page, but it doesn't actually show it, it returns a string), or: would the 'page' class be a controller?

Normalmente index.php diventa il front controller o il bootstrap.

Crei alcune cartelle: library , controllers , models e views , quindi li carichi tutti da index.php .

Quindi crei una classe Route nella cartella delle tue librerie, che dovrebbe essere in grado di analizzare PHP REQUEST_URI in controller class name , method name e array of parameters .

Nel tuo index.php , puoi creare un'istanza di un nuovo Route con PHP REQUEST_URI ad esso, quindi chiami il metodo Route::build , che dovrebbe essere in grado di instire un controller, quindi chiamare il suo metodo che corrisponde al parsed PHP REQUEST_URI . (Ulteriori informazioni su call_user_func_array ).

Il metodo del controller restituisce una stringa (da un file di visualizzazione o da qualsiasi altra cosa), quindi puoi semplicemente stamparlo sul browser.

Qui ti darò un esempio minimo di MVC in PHP:

core.php

<?php

class Route
{
  protected $class;

  protected $method;
  protected $params = array();

  /**
   * Parse the given URI, if the URI is "site/article/10", then "site" will be
   * the controller class, "article" will be the method, and "10" will be 
   * the parameter.
   */
  function __construct($uri)
  {
    $segments = explode('/', $uri);

    foreach ($segments as $segment)
    {
      if ($this->class === NULL)
      {
        $this->class = ucfirst($segment);
      }
      else if ($this->method === NULL)
      {
        $this->method = $segment;
      }
      else
      {
        $this->params[] = $segment;
      }
    }
  }

  /**
   * Instantiate a controller class then execute the method with the parameters from 
   * the parsed REQUEST_URI.
   */
  function call(Database $database)
  {
    $controller = new $this->class($database);

    $response = call_user_func_array(array($controller, $this->method), $this->params);

    return $response;
  }
}

class Controller
{
  function __construct(Database $database)
  {
    $this->database = $database;
  }

  /**
   * Instantiate a model
   */
  function model($name)
  {
    $model = new $name($this->database);

    return $model;
  }
}

class View
{
  protected $data = array();
  protected $path;

  function __construct($path, array $data = array())
  {
    $this->path = $path;
    $this->data = $data;
  }

  function render()
  {
    // Extract the data so you can access all the variables in
    // the "data" array inside your included view files
    ob_start(); extract($this->data);

    try
    {
      include $this->path;
    }
    catch(\Exception $e)
    {
      ob_end_clean(); throw $e;
    }

    return ob_get_clean();
  }

  /**
   * Make it able for you to write a code like this: echo new View("home.php")
   */
  function __toString()
  {
    return $this->render();
  }
}

class Model
{
  protected $database;

  function __construct(Database $database)
  {
    $this->database = $database;
  }
}

class Database
{
  function __construct()
  {
    // Connect to the database, for example: mysql_connect($host, $user, $pass, $data)
  }

  function query($sql)
  {
    // Do some database query like usual, for example: mysql_query($sql)
  }
}

index.php:

<?php

require "core.php"

class Article extends Model
{
  function find($id)
  {
    // You execute query through $this->db->query("SELECT..."), but i'll just use an array
    // to simplify things.
    return array("title" => "Article", "body" => "Lorem Ipsum");
  }
}

class Site extends Controller
{
  function article($id)
  {
    $article_model = $this->model("Article");

    // This is how you use the view class!
    $view = new View("article.php", array("article" => $article_model->find($id)));

    return $view;
  }
}

// This is where everything starts
$route = new Route("site/article/10");
echo $route->call(new Database());

article.php :

<h1><?php echo $article['title'] ?></h1>
<p><?php echo $article['body'] ?></p>

Inserisci article.php , index.php e core.php in una cartella, quindi esegui index.php dal tuo browser.

    
risposta data 13.05.2013 - 22:23
fonte

Leggi altre domande sui tag