2. Un approccio di sviluppo MVC per Web/PHP
Qui proponiamo un approccio per lo sviluppo di applicazioni web/PHP basate sull'architettura MVC. Il nostro intento è solo quello di fornire un punto di partenza. Il lettore è invitato ad adattarlo alle proprie preferenze ed esigenze.
- Inizieremo definendo tutte le viste dell'applicazione. Si tratta delle pagine web presentate all'utente. Adotteremo la prospettiva dell'utente nella progettazione delle viste. Esistono tre tipi di viste:
- il modulo di input, progettato per raccogliere informazioni dall'utente. In genere include un pulsante per inviare le informazioni inserite al server.
- La pagina di risposta, che serve solo a fornire informazioni all'utente. Spesso include uno o più link che consentono all'utente di continuare a utilizzare l'applicazione su un'altra pagina.
- la pagina mista: il controller ha inviato al client una pagina contenente le informazioni che ha generato. Questa stessa pagina verrà utilizzata dal client per fornire al controller nuove informazioni provenienti dall'utente.
- Ogni vista genererà una pagina PHP. Per ciascuna di queste:
- progetteremo il layout della pagina
- determineremo quali parti di essa sono dinamiche:
- le informazioni destinate all'utente che devono essere fornite dal controller come parametri alla vista PHP. Una soluzione semplice è la seguente:
- Il controller inserisce le informazioni che desidera fornire a una vista V in un dizionario $dResponse
- Il controller visualizza la vista V. Se questa corrisponde al file sorgente V.php, la visualizzazione si ottiene semplicemente con l'istruzione include V.php.
- L'inclusione precedente è un'inclusione di codice all'interno del controller. Il dizionario $dResponse popolato dal controller è direttamente accessibile dal codice in V.php.
- I dati di input che devono essere trasmessi al programma principale per l'elaborazione. Questi dati devono far parte di un modulo HTML (tag <form>).
- le informazioni destinate all'utente che devono essere fornite dal controller come parametri alla vista PHP. Una soluzione semplice è la seguente:
- Possiamo schematizzare l'I/O per ciascuna vista
![]() |
- Gli input sono i dati che il controller deve fornire alla pagina PHP
- Gli output sono i dati che la pagina PHP deve fornire al controller dell'applicazione. Fanno parte di un modulo HTML e il controller li recupererà utilizzando un'operazione come $_GET["param"] (metodo GET) o $_POST["param"] (metodo POST).
- Spesso, la pagina finale inviata al client non è una singola vista, ma una composizione di viste. Ad esempio, la pagina inviata a un utente potrebbe apparire così:
![]() |
L'area 1 può essere un banner di intestazione, l'area 2 un banner di menu e l'area 3 un'area di contenuto. In PHP, questa composizione può essere ottenuta utilizzando il seguente codice HTML/PHP:
<table>
<tr>
<td><?php include zone1.php ?></td>
</tr>
<tr>
<td><?php include zone2.php ?></td>
<td><?php include zone3.php ?></td>
</tr>
</table>
È possibile rendere questo codice dinamico scrivendo:
<table>
<tr>
<td><?php include $dReponse['urlZone1'] ?></td>
</tr>
<tr>
<td><?php include $dReponse['urlZone2'] ?></td>
<td><?php include $dReponse['urlZone3'] ?></td>
</tr>
</table>
Questa composizione della vista può essere l'unico formato della risposta inviata all'utente. In questo caso, ogni risposta al client deve impostare i tre URL da caricare nelle tre zone prima di visualizzare la pagina di risposta. Possiamo generalizzare questo esempio immaginando che esistano diversi modelli possibili per la pagina di risposta. La risposta al client deve quindi:
- determinare il modello da utilizzare
- determinare gli elementi da includere in essa
- richiedere la visualizzazione del modello
- Scriveremo il codice PHP/HTML per ciascun modello di risposta. Il codice è generalmente semplice. Il codice per l'esempio sopra riportato potrebbe essere:
<?php
// initializations for testing without a controller
...
?>
<html>
<head>
<title><?php echo $dReponse['titre'] ?></title>
<link type="text/css" href="<?php echo $dReponse['style']['url'] ?>" rel="stylesheet" />
</head>
<body>
<table>
<tr>
<td><?php include $dReponse['urlZone1'] ?></td>
</tr>
<tr>
<td><?php include $dReponse['urlZone2'] ?></td>
<td><?php include $dReponse['urlZone3'] ?></td>
</tr>
</table>
<body>
</html>
Quando possibile, useremo un foglio di stile in modo da poter modificare l'aspetto della risposta senza dover modificare il codice PHP/HTML.
- Scriveremo il codice PHP/HTML per ogni vista di base. Il più delle volte assumerà la seguente forma:
<?php
// a few initializations may be necessary, particularly in the debugging phase
...
?>
<balise>
...
// here we'll try to minimize the php code
</balise>
Si noti che una vista di base è incorporata in un modello. Il suo codice HTML è integrato nel codice del modello. Molto spesso, il modello include già i tag <html>, <head> e <body>. È quindi raro trovare questi tag in una vista di base.
- Possiamo procedere a testare i vari modelli di risposta e le viste di base
- Ogni modello di risposta viene testato. Se un modello si chiama modele1.php, richiederemo l'URL http://localhost/chemin/modele1.php utilizzando un browser. Il modello si aspetta valori dal controller. In questo caso, lo chiamiamo direttamente anziché tramite il controller. Il modello non riceverà i parametri previsti. Per consentire comunque il test, inizializzeremo manualmente i parametri previsti nella pagina PHP del modello utilizzando delle costanti.
- Ogni modello viene testato, così come tutte le viste di base. Questo è anche il momento di sviluppare i primi elementi dei fogli di stile utilizzati.
- Successivamente, scriviamo la logica dell'applicazione:
- Il controller, o programma principale, gestisce generalmente diverse azioni. L'azione da eseguire deve essere definita nelle richieste che riceve. Ciò può essere fatto utilizzando un parametro di richiesta, che qui chiameremo `action`:
- se la richiesta proviene da un modulo (<form>), questo parametro può essere un parametro nascosto del modulo:
<form ... action="/C/main.php" method="post" ...>
<input type="hidden" name="action" value="uneAction">
...
</form>
- (continua)
- Se la richiesta proviene da un link, è possibile configurarla come segue:
Il controller può iniziare leggendo il valore di questo parametro e poi delegare l'elaborazione della richiesta a un modulo incaricato di gestire questo tipo di richiesta. In questo caso, abbiamo ipotizzato che tutto sia gestito da un unico script chiamato main.php. Se l'applicazione deve gestire le azioni action1, action2, ..., actionx, è possibile creare una funzione per ciascuna azione all'interno del controller. Se le azioni sono molte, ciò può portare a un controller "dinosaurio". In alternativa, è possibile creare script action1.php, action2.php, ..., actionx.php responsabili della gestione di ciascuna azione. Il controller incaricato di gestire l'azione actionx caricherà semplicemente il codice dallo script corrispondente utilizzando un'istruzione come include "actionx.php". Il vantaggio di questo metodo è che si lavora al di fuori del codice del controller. Ogni membro del team di sviluppo può quindi lavorare sullo script che gestisce un'azione actionx in modo relativamente indipendente. Includere il codice dallo script actionx.php nel codice del controller in fase di esecuzione ha anche il vantaggio di ridurre la quantità di codice caricato in memoria. Viene caricato solo il codice per la gestione dell'azione corrente. Questa inclusione di codice implica che le variabili del controller potrebbero entrare in conflitto con quelle presenti nello script dell'azione. Vedremo che è possibile limitare le variabili del controller a poche ben definite, che dovrebbero quindi essere evitate negli script.
- Cercheremo sistematicamente di isolare la logica di business o il codice per l'accesso ai dati persistenti in moduli separati. Il controller agisce come una sorta di caposquadra che riceve le richieste dai propri clienti (client web) e le fa eseguire dalle entità più appropriate (i moduli di business). Durante la scrittura del controller, determineremo l'interfaccia dei moduli di business da scrivere. Ciò vale se questi moduli di business devono essere realizzati. Se esistono già, il controller si adatterà all'interfaccia di questi moduli esistenti.
- Scriveremo lo scheletro dei moduli di business richiesti dal controller. Ad esempio, se il controller utilizza un modulo `getCodes` che restituisce un array di stringhe, inizialmente possiamo semplicemente scrivere:
- Possiamo quindi passare al test del controller e degli script PHP associati:
- il controller, gli script di azione, i modelli, le viste e le risorse richieste dall'applicazione (immagini, ecc.) vengono collocati nella cartella DC associata al contesto C dell'applicazione.
- Una volta fatto ciò, l’applicazione viene testata e gli errori iniziali vengono corretti. Se main.php è il controller e C è il contesto dell’applicazione, richiederemo l’URL http://localhost/C/main.php. Al termine di questa fase, l’architettura dell’applicazione è operativa. Questa fase di test può essere impegnativa, dato che sono disponibili pochi strumenti di debug se non si utilizzano ambienti di sviluppo avanzati, che sono generalmente a pagamento. È possibile utilizzare le istruzioni echo "message", che scrivono nel flusso HTML inviato al client e quindi appaiono sulla pagina web visualizzata dal browser.
- Infine, scriviamo le classi di business richieste dal controller. Ciò comporta tipicamente lo sviluppo standard di una classe PHP, che di solito è indipendente da qualsiasi applicazione web. Verrà prima testata al di fuori di questo ambiente, utilizzando ad esempio un'applicazione console. Una volta scritta una classe di business, la integriamo nell'architettura di distribuzione dell'applicazione web e ne verifichiamo la corretta integrazione. Procediamo in questo modo per ogni classe di business.

