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

Pattern MVC e routing: la classe Dispatcher

Continuiamo a sviluppare il nostro e-commerce in PHP analizzando il funzionamento del routing nel pattern MVC (Model-view-controller).
Continuiamo a sviluppare il nostro e-commerce in PHP analizzando il funzionamento del routing nel pattern MVC (Model-view-controller).
Link copiato negli appunti

Nel precedente capitolo abbiamo accennato al routing nel pattern MVC mostrando il file .htaccess che stiamo usando. Abbiamo visto come tutte le richieste che non puntino a file e directory esistenti vengano reindirizzate sul file index.php. In questo capitolo ne vedremo i dettagli.

Sostanzialmente si tratta di correlare le parti di un URL di una richiesta ad un controller specifico e ad un suo metodo pubblico che può a volte accettare argomenti.

Quindi dato un URL come:

/pages/view/8

l’URL va scomposto esplodendone le parti separate dal carattere / che corrisponderanno al controller, al suo metodo e all’argomento del metodo partendo da sinistra. Avremo:

class Pages {
   public function view($id) {
   }
}

Notiamo già un problema: il nome della classe è Pages mentre il frammento dell’URL è pages in minuscolo. Inoltre view potrebbe essere scritto come view-page e il metodo corrispondente essere quindi viewPage in notazione camel-case. Come risolvere queste discrepanze?

Per far questo dobbiamo creare una classe Dispatcher che effettui il parsing dell’URL delle richieste, carichi il controller corrispondente e risolva le discrepanze a cui accennavamo.

La classe è la seguente:

class Dispatcher {
    protected $params;
    protected $controller;
    public function __construct($controller) {
        $this->controller = $controller;
        $this->params = $this->parse($_SERVER['REQUEST_URI']);
    }
    public function handle() {
        $action = $this->params['method'];
        $args = $this->params['args'];
        if(method_exists($this->controller, $action)) {
            if(!is_null($args)) {
                $this->controller->$action($args);
            } else {
                $this->controller->$action();
            }
        } else {
            Site::error();
        }
    }
    protected function parse($path) {
        if($path == '/') {
            return [
                'method' => 'index',
                'args' => null
            ];
        } else {
            $parts = array_values(array_filter(explode('/', $this->removeQueryStringVariables($path))));
            $method = $this->convertToCamelCase($parts[0]);
            $args = array_slice($parts, 1);
            return [
                'method' => $method,
                'args' => (count($args) > 0 ) ? $args : null
            ];
        }
    }
    protected function convertToStudlyCaps($string) {
        return str_replace(' ', '', ucwords(str_replace('-', ' ', $string)));
    }
    protected function convertToCamelCase($string) {
        return lcfirst($this->convertToStudlyCaps($string));
    }
    protected function removeQueryStringVariables($url) {
        $parts = explode('?', $url);
        return $parts[0];
    }
}

I metodi fondamentali sono parse() e handle(). Il primo accetta come argomento l’URL della richiesta HTTP. Se corrisponde a / siamo nella home del sito. Altrimenti il percorso viene esploso e vengono subito rimosse le eventuali variabili aggiunte da una query string GET. Quindi viene estratto il nome del metodo convertito in notazione camel-case e i suoi eventuali argomenti.

L’output restituito è un array associativo in cui la voce method corrisponde al metodo del controller e args è un array lineare di argomenti del metodo.

Il metodo handle() utilizza parse() per ottenere il nome del metodo e i suoi parametri. Se il metodo esiste nel controller, viene invocato con i suoi argomenti (o senza argomenti se non ve ne sono).

Dato che il nostro e-commerce è molto semplice, usiamo un solo controller, ossia la classe Shop che abbiamo già visto a titolo di esempio in precedenza.

Se avete più controller, semplicemente il primo elemento dell’array delle parti del path diventa il nome del vostro controller che poi potete includere e istanziare prima di invocarne il metodo.

Conclusione

In questo capitolo abbiamo visto il funzionamento del routing nel pattern MVC. Nel prossimo capitolo vedremo il pattern MVC in relazione con i namespace e l’autoloading in PHP.

Ti consigliamo anche