Salta el contingut

Routing i controladors

Una de les tasques que ha de realitzar el nostre controlador frontal és enrutar, és a dir, analitzar la sol·licitud de l'usuari i activar el mètodo del controlador associat.

Així una ruta serà una url que ens donarà accés a un controlador. És important, a l'hora de definir les rutes seguir una convenció, nosaltres seguirem aquesta: REST resource naming.

El router: AltoRouter

Aquesta funció la realitzarem des d'un compoment que s'encarregarà de:

  1. Gestionar la taula de rutes, on es vincula cada ruta a un controlador.
  2. Resoldre les sol·licituds, és a dir, buscar el controlador vinculat a la ruta.

En el projecte usarem AltoRouter un component que s'ajusta perfectament a les nostres necessitats.

L'instal·lem:

composer require altorouter/altorouter

En aquest exemple podem vore les seues opcions de mapeig:

$router = new AltoRouter();

// map homepage
$router->map('GET', '/', function() {
    require __DIR__ . '/views/home.php';
});

// dynamic named route
$router->map('GET|POST', '/users/[i:id]/', function($id) {
  $user = .....
  require __DIR__ . '/views/user/details.php';
}, 'user-details');

// map controller
$router->map('GET', '/', 'MovieController#list', 'movie_list');

// map controller with params
$router->map('GET|POST', '/movies/[i:id]/edit', "MovieController#edit", 'movie_edit');

// echo URL to user-details page for ID 5
echo $router->generate('user-details', ['id' => 5]); // Output: "/users/5"
I la forma de resoldre les sol·licituds amb el mètode match() que torna el nom del controlador a activar.

$match = $router->match();

Una vegada obtingut el controlador caldrà executar-lo:

if (is_array($match)) {
    $temp = explode("#", $match["target"]);
    $controller = $prefix . $temp[0];
    $action = $temp[1];
    if (method_exists($controller, $action)) {
        $object = new $controller;
        call_user_func_array([$object, $action], $match['params']);
    } else {
        // no route was matched
        header($_SERVER["SERVER_PROTOCOL"] . ' 404 Not Found');
        echo "error";
    }
} else {
    // no route was matched
    header($_SERVER["SERVER_PROTOCOL"] . ' 404 Not Found');
    echo "error";
}

Els controladors

Com hem vist en la introducció, el controlador és el component del patró MVC que s'encarrega de rebre la sol·licitud de l'usuari, interactuar en el model i la vista i retornar la informació al client.

Els controladors solen implementar-se en una classe, els mètodes de la qual, són les diferents accions que es poden realitzar.

Per exemple:

namespace App\Controller;

...
class MovieController
{
    const MAX_SIZE = 1024 * 1000;
    private MovieRepository $movieRepository;

    public function __construct()
    {
        $mapper = new MovieMapper();
        $this->movieRepository = new MovieRepository($mapper);
    }

    public function list()
    {
        $movies = $this->movieRepository->findAll();

        $logger = Registry::get(Registry::LOGGER);
        $logger->info("s'ha executat una consulta");

        require __DIR__ . "/../../views/index.view.php";
    }
    ...
}

En aquest exemple, en sol·licitar la pàgina principal ("/"), el enrutador activaria el mètode list del controlador MovieController que obté les pel·lícules mitjançant el repositori. Com que la vista, a hores d'ara, es troba en el mateix àmbit d'execució, podrà accedir a les dades generades i mostrar-les.