Il Model-View-Controller (MVC) è un pattern architetturale molto usato per lo sviluppo di applicazioni web.Il pattern ci permette di costruire applicazioni a tre stati (3-tier applications) in cui sia lo sviluppatore sia il design possono collaborare al fine di ottenere applicazioni web mantenibili ed espandibili a tutto vantaggio di quest'ultime.
Per capirne meglio il funzionamento, in questa immagine, gentilmente offerta da bpat1434 del phpbuilder forum, trovi lo schema logico del MVC.
L'utente spedisce l'input che va al controller.Il controller poi inoltra quell'input al corretto model, che effettua tutto il duro lavoro e restituisce le informazioni richieste.Il controller riceve queste informazioni e le inoltra alla view.A questo punto, la view può o spedire direttamente l'output tramite un echo al browser o ritornarlo al controller che lo invierà all'utente.
Adesso bando alle chiacchere e veniamo al sodo dello script, ecco una bozza di Uml:
UserDataSetter parent di : - UserData UserData aggregation con : - UserValidation - UserMail -- composition con : -- UserModel UserValidation extend Validator : - composition con : -- UserModel Mail composition con : - UserMail composition con : -- UserModel PDO aggregation con : - UserModel aggregation con : -- UserController UserView aggregation con : - UserPage composition con : -- UserControllere la sua traduzione in codice :
Codice php:
class UserDataSetter {
protected $data= array(
'id'=>'',
'nickname'=>'',
'username'=>'',
'password'=>'',
'email'=>'',
'uid'=>'',
'list'=>array()
);
public function __get($nm){}
protected function __set($nm, $val){}
}
abstract class UserValidator extends Validator{
protected $data= null;
public function __construct(UserDataSetter $data){
/* aggregation */
$this->data= $data;
}
abstract protected function validation();
}
abstract class UserMail{
protected $data= null;
protected $subject= '';
protected $body= '';
public function __construct(UserDataSetter $data){
/* Aggregation */
$this->data= $data;
}
public function send(){
/* Istanza classe Mail composition */
}
abstract protected function setBody();
abstract protected function setSubject();
}
abstract class UserModel{
protected $db= null;
protected $data= null;
public function __construct(PDO $db){
$this->db= $db;
}
abstract protected function setData();
abstract protected function execute();
}
abstract class UserView{
protected $xhtml= '';
abstract protected function setView();
public function getView(){
return $this->xhtml;
}
}
class UserPage{
private $title= '';
private $xhtml= '';
public function __construct($title,UserView $view){
$this->setTitle($title);
$this->buildHeader();
$this->buildView($view);
$this->buildFooter();
}
private function setTitle($title){}
private function buildHeader(){}
public function buildView($view){
$this->xhtml.= $view->getView();
}
private function buildFooter(){}
public function getXhtml(){
return $this->xhtml;
}
final public function __destruct(){
unset($this->xhtml);
}
}
abstract class UserController{
protected $db= null;
protected $page= null;
public function __construct(PDO $db){
$this->db= $db;
}
abstract protected function run();
public function getPage(){
return $this->page->getXhtml();
}
}
Per ogni compito dello script vi è una abstract class che funge da modello e che verrà estesa per ogni modulo (registrazione,login,reset) che dovrà implementare concretamente i metodi dichiarati astratti dalla classe parent.
Il costruttore delle classi utilizza il Type Hinting che obbliga il parametro ad essere un oggetto della particolare classe indicata.
Rimando i lettori che non hanno familiarità con aggregation e composition all'articolo The PHP Anthology Volume 1, Chapter 2 - Object Oriented PHP su Sitepoint (veramente un eccelente libro per espandere la Ns. conoscenza di php).
Conclusioni
Spero ti sarai fatto un'idea di massima del funzionamento logico dello script, se così non fosse non scoraggiarti, nel prossimo articolo parlerò del piccolo framework utilizzato dallo script per quei compiti non strettamente legati al MVC e sarà pieno di esempi concreti (i miei preferiti ;) puoi .