Utilizzo di PDO con MVC

3

Ho posto questa domanda a StackOverflow e non ho ricevuto risposta (chiusa come duplicata senza risposta). Sto sperimentando con OOP e ho il seguente layout MVC di base:

class Model {
    // do database stuff
}

class View {
    public function load($filename, $data = array()) {
        if(!empty($data)) {
            extract($data);
        }

        require_once('views/header.php');
        require_once("views/$filename");
        require_once('views/footer.php');
    }
}

class Controller {
    public $model;
    public $view;

    function __construct() {
        $this->model = new Model();
        $this->view = new View();

        // determine what page we're on
        $page = isset($_GET['view']) ? $_GET['view'] : 'home';
        $this->display($page);
    }

    public function display($page) {
        switch($page) {
            case 'home':
                $this->view->load('home.php');
            break;
        }
    }
}

Queste classi sono riunite nel mio file di installazione:

// start session
session_start();

require_once('Model.php');
require_once('View.php');
require_once('Controller.php');

new Controller();

Ora dove inserisco il mio codice di connessione al database e come faccio a passare la connessione al modello?

try {
    $db = new PDO('mysql:host='.DB_HOST.';dbname='.DB_DATABASE.'', DB_USERNAME, DB_PASSWORD);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $err) {
    die($err->getMessage());
}

Ho letto di Dependency Injection, delle fabbriche e di altri modelli di design diversi che parlano di come mantenere SQL fuori dal modello, ma è tutto da capo con esempi astratti. Qualcuno può per favore mostrarmi un esempio pratico semplice?

    
posta mister martin 09.12.2012 - 16:16
fonte

2 risposte

3

Come Falcon ha menzionato, il codice di accesso ai dati dovrebbe essere in Controller , almeno l'unico accesso a un livello di servizio o livello di accesso ai dati dovrebbe essere fatto da Controller . Il Model è usato principalmente per strutturare i dati che vuoi mostrare nella vista, in altre parole dovrebbe imitare il tuo modello di dominio. In genere, devi eseguire query sui dati dal database, creare un Model con i dati, caricare Model su View , il tutto all'interno del tuo Controller (in termini generali, l'implementazione potrebbe essere diversa).

Nel tuo esempio, potrebbe apparire come questo (di nuovo, solo un esempio di panoramica),

class Model {
    // domain model properties: id, name, age... 
}

class View {
    // view stuff        
}

class Repository {
    function __construct() {
       // connect to database and return a viable connection for data access
    }
}

class Controller {
    public $model;
    public $view;
    public $repository   

    function __construct() { 
        $this->repository = new Repository();       

        $this->model = new Model();
        $this->model = $this->repository.LoadModelFromDatabase();

        // load your model onto the view
        $this->view = new View($this->model);

        // determine what page we're on
        $page = isset($_GET['view']) ? $_GET['view'] : 'home';

        // display your view with your model loaded
        $this->display($page);
     }

     public function display($page) {
         switch($page) {
             case 'home':
                 $this->view->load('home.php');
             break;
     }
}

Dovresti seguire un modello simile per altri Views e Models , utilizzando il tuo Controller per coordinare l'accesso al database e l'interazione con il tuo programma.

    
risposta data 09.12.2012 - 19:04
fonte
0

Dipende tutto da quanto design e astrazione vuoi inserire nel tuo codice. Il tuo codice va bene se vuoi mantenere le cose relativamente semplici e avere flessibilità senza troppi grattacapi o scrivere codice. Metti il tuo accesso al database in un oggetto dedicato, che estrarrà i dati del DB e costruirà il tuo Model oggetto per te (è una fabbrica). Quindi, all'interno del metodo del controller, interrogare tale factory per recuperare l'istanza del modello corretta per popolare la vista. Il modello stesso non ha realmente bisogno di sapere da dove proviene, quindi la fabbrica è libera di costruirlo da un archivio basato su file. Le uniche cose di cui avrà bisogno la tua fabbrica sono alcuni parametri (ad esempio i campi di $_GET rilevanti nel tuo codice), per capire quali dati deve recuperare.

class ModelFactory {
    private $dbhandle;
    function __construct(){
          // open db etc...
    }
   function loadModel($params){
         // run db queries and construct/fill up the Model instance
   }
   function saveModel($model){
        // pull out model fields to fill the insert/update query
   }
   // etc...you get the idea
}

Successivamente, se si dispone di un livello di base del modello in cui gli oggetti di dominio sono trasposizioni dirette delle righe del database, come nel caso dell'uso diretto del pattern ActiveRecord, è sufficiente lasciare l'utente finale CRUD operazioni, quindi fallo. Prendi ispirazione da quel modello per costruire il tuo ORM su di esso, e ottieni Master / Dettaglio di base, uno a molti, molti a molti rapporti gestiti per te. Questo sarebbe un primo passo nella giusta direzione (puoi dare un'occhiata alle prime versioni di Cakephp o Code Igniter per avere un'idea di come funziona), ma se vuoi farlo nel modo giusto (TM), allora vedi che MVC può essere molto più complicato.

L'architettura MVC è in realtà più astratta di quella. La parte del modello è un "livello" nell'applicazione, che comprende un insieme di diversi servizi , in un senso molto ampio, che fondamentalmente ti consente di incorporare funzionalità "di livello superiore" (ad esempio l'autenticazione, dove è necessario estrarre i dati da posizioni diverse, ma questi dettagli non dovrebbero trapelare al livello del controller), che può essere utilizzato in diverse richieste, quindi oggetti di dominio (come un utente), quindi mappatori di dati (come il pattern ActiveRecord).

Ci sono messaggi eccellenti su SO su quell'argomento, come questo , che copre l'argomento in dettaglio.

    
risposta data 10.12.2012 - 13:44
fonte

Leggi altre domande sui tag