Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Analisi di un framework MVC in PHP

Costruiamo il nostro framework MVC: introduzione al modello di programmazione e componenti fondamentali
Costruiamo il nostro framework MVC: introduzione al modello di programmazione e componenti fondamentali
Link copiato negli appunti

L'architettura di un software è fondamentale sia per la riuscita di un progetto entro i termini stabiliti sia per rendere il progetto stesso mantenibile ed aggiornabile nel tempo. Da quando si è sviluppato il concetto di Web 2.0 l'attenzione si è spesso focalizzata sulla parte client delle applicazioni e sul loro look and feel, lasciando in disparte la, quanto meno, fondamentale parte server.

Dal punto di vista dello scripting web (o della programmazione se preferite)  sono andati sempre di più ad affermarsi i framework MVC. Ruby on Rails è stato sicuramente quello che per primo ha destato l'interesse di un gran numero di sviluppatori che hanno visto nel pattern MVC e nei framework RAD (Rapid Application Development) una sorta di rinnovata (perché parlare di nuova sarebbe sicuramente eccessivo) e ritrovata concezione dello sviluppo web.

Il continuo crescere dell'interesse ha causato la nascita di decine di progetti simili sviluppati in altri linguaggi, sia seguendo lo stesso concetto di base che adattandolo alle esigenze specifiche di alcune situazioni; la base MVC è però rimasta sempre dato che la separazione tra i concetti di dati, aspetto e comportamento semplifica notevolmente i processi di sviluppo e i futuri interventi sul codice.

Oggi inizierò una serie di articoli in cui introdurrò allo sviluppo di un framework MVC puntando soprattutto sulla parte teorica, cercando di focalizzare l'attenzione su quei concetti che sono alla base di tutti i framework di successo in modo da rendere più completa la conoscenza di questo argomento al lettore. Il framework che andremo ad implementare sarà scritto in PHP 5 e non avrà né l'obiettivo di essere il nuovo Ruby on Rails né di competere con gli ottimi prodotti commerciali e free che attualmente intasano il mercato (e di cui abbiamo già accennato qualcosa in precedenti articoli). L'obiettivo sarà puramente didattico sperando che da tutto il discorso si riescano a trarre delle buone conclusioni che potranno aiutare all'eventuale evoluzione dei concetti presentati.

Descrizione del pattern MVC

Prima di parlare di come vorrei strutturare il framework, è d'obbligo introdurre e descrivere il pattern MVC. Ho già introdotto questo concetto in altri articoli, ma comunque riassumerò qui ciò che è stato detto precedentemente in modo da raggruppare tutte le informazioni utili in un unica risorsa.

Il pattern MVC è una metodologia che propone di separare un'applicazione o una porzione di questa in tre parti separate: il modello, la vista ed il controller. Il pattern MVC è stato inizialmente sviluppato per rimappare il tradizionale concetto di input -> elaborazione -> output che si era soliti utilizzare nello sviluppo di applicazioni shell nel dominio delle applicazioni GUI (e nel nostro caso delle applicazioni web). L'input dell'utente, il modello dei dati ed il feedback visuale all'utente sono separati e gestiti dal modello, dalla vista e dal controller.

Il controller interpreta i dati in input provenienti dall'utente e rimappa questi dati in comandi che sono inviati al modello ed eventualmente alla vista per effettuare le opportune variazioni. Il modello gestisce i dati, risponde alle richieste sullo stato ed esegue le istruzioni di modifica dello stato stesso. La vista invece visualizza i dati all'utente combinandoli con della grafica e del testo aggiuntivo.

Ogni singolo modello contiene solamente i dati e le funzionalità che sono relative ad un concetto comune; in caso si dati rappresentanti informazioni differenti, questi saranno rappresentati a loro volta da modelli differenti. Un modello si occupa anche di controllare l'effettiva validità dei dati assegnati e l'effettiva correttezza dell'ordine in cui sono effettuate le operazioni su di lui. Se alcune operazioni necessitano l'intervento su altri modelli, questi ultimi sono notificati del cambiamento che viene correttamente applicato.

La vista è responsabile di visualizzare i dati dei modelli direttamente all'utente aggiungendo della grafica e del testo che rendano comprensibili i dati visualizzati; ogni modifica al modello a cui la vista fa riferimento comporta il ridisegno della vista stessa in modo che l'utente visualizzi sempre dati aggiornati. Un modello può avere molteplici viste associate ed ognuna di queste viste può visualizzare i dati del modello utilizzando rappresentazioni diverse in base al contesto.

Infine un controller è il componente tramite il quale l'utente interagisce con l'applicazione. Un controller accetta l'input dall'utente ed utilizza i modelli e le viste definite per rispondere alle richieste effettuate. In pratica si occupa di rimappare le azioni effettuate dall'utente (che nel caso di un'applicazione web possono essere le chiamate ad un determinato URL e/o l'invio di dati) alle risposte dell'applicazione, che lavoreranno sui modelli e le viste in modo adeguato.

I tre concetti sono strettamente correlati tra loro: ogni modifica al modello deve essere invocata dal controller e deve notificare la vista in modo che l'applicazione funzioni in modo corretto.

Nel campo dello sviluppo web solitamente le azioni intraprese da un utente si possono riassumere nella richiesta di un URL al quale possono essere inviati opzionalmente dei dati. Il controller è uno script associato ad una determinata azione (URL) che carica i modelli appropriati e renderizza il risultato sulla vista corretta; una vista non è altro che un template che visualizza i dati inviati dal controller successivamente all'eventuale elaborazione dei modelli; un modello infine non è altro che una sorgente di dati (assimilabile ad un file di testo o una tabella SQL) a cui sono associati una serie di script per manipolarla.

La struttura del nostro framework

Dopo aver introdotto il pattern MVC dal punto di vista teorico possiamo passare a descrivere attivamente come sarà strutturato il nostro framework. Per poter comprendere in modo più approfondito il funzionamento di ogni singolo componente che andremo ad implementare, ho deciso di non basarmi su nulla di già pronto reperibile sulla rete. Ovviamente questo limiterà le potenzialità del framework, soprattutto dal punto di vista del sistema di persistenza degli oggetti usato per i modelli e del template engine, ma ci permetterà di analizzare anche quelle parti che normalmente sono tralasciate da articoli con contenuti simili.

Il nostro framework farà largo uso dei nuovi concetti introdotti in PHP 5, come la gestione delle eccezioni, la programmazione ad oggetti avanzata, la reflection API e l'overload. Per questo motivo consiglio a chi non avesse ancora una conoscenza per lo meno teorica dei concetti di reperire sulla rete qualche articolo in proposito e leggerli così da evitare di perdersi sugli argomenti di supporto al contenuto degli articoli.

Il framework sarà composto da una serie di componenti. Ogni componente sarà a conoscenza degli altri e si appoggerà ad eventuali funzionalità di supporto che saranno implementate e descritte quando si andrà a sviluppare il componente stesso o quando si applicheranno delle modifiche agli altri componenti che richiederanno l'aggiornamento di queste utilità. I componenti saranno implementati come delle classi e si cercherà di utilizzare molto i concetti della programmazione ad oggetti (come ereditarietà, incapsulamento, design patter e così via) in modo da rendere il framework facilmente aggiornabile ove necessario.

I componenti principali del framework saranno i seguenti:

  • PersistentObject: rappresenta un oggetto che esporrà una serie di funzionalità che gli permetteranno di essere salvato e recuperato automaticamente da un database SQL. Non fornirà le funzionalità avanzate di un framework di persistenza, ma si limiterà ad esporre alcuni getter/setter utili e strumenti per la serializzazione/deserializzazione dell'oggetto.
  • Model: rappresenta una versione speciale di PersistentObject che aggiunge strumenti per la validazione dei dati. Tutti i modelli utilizzabili dai componenti e renderizzabili dalle viste verranno estesi da questa classe base.
  • Template: rappresenta un template testuale che verrà analizzata ed interpretata in modo da renderizzare i dati assegnati in fase di costruzione. Per semplificare la stesura dell'engine i template saranno dei file XML contenenti attributi speciali per controllare la generazione dell'output (in modo simile a PHPTal ma non così avanzato).
  • Controller: rappresenta un insieme di azioni che potrebbero essere intraprese dall'utente. Ogni azione verrà rappresentata da un metodo definito nelle classi che estenderanno Controller; i metodi verranno richiamati in base a determinate condizioni e dovranno restituire una stringa che verrà inviata in output all'utente (solitamente un Template renderizzata). Ogni metodo potrà avere un commento opzionale nel quale potranno essere assegnate delle proprietà specifiche per la singola azione (come ad esempio i permessi di accesso - che verranno però implementati in un secondo momento).
  • Router: il router è una classe che si occupa di rimappare le richieste HTTP a chiamate alle azioni dei controller. Inizialmente implementeremo un router nel quale andranno registrate esplicitamente le mappature tra URL e azioni; successivamente estenderemo il concetto ed implementeremo un router che analizzerà determinate directory del filesystem per recuperare, in base all'URL richiesto, il controller corretto.
  • Application: rappresenta il collante tra PHP ed il framework MVC. Verrà implementato come singleton e conterrà tutte le informazioni sullo stato delle chiamate e delle richieste HTTP.

Conclusione

Come possiamo notare il framework che andremo ad implementare non è eccessivamente complesso, ma tocca gran parte dei punti fondamentali per una corretta comprensione dei concetti che andremo ad analizzare. Nel prossimo articolo inizieremo a descrivere ed implementare le basi del framework, implementando alcune funzioni di utilità e la prima versione del componente Application.

Ti consigliamo anche