Vuelvo con este tema que es la segunda parte del patrón MVC, y es el FrontController, en el tema pasado vimos como es posible separar la capa de datos/proceso/vista, es una forma ideal para separar nuestro código y hacerlo mucho mas legible.
Ahora vamos a ver como centralizar todo y controlar las instancias. En un ambiente como Java o C, siempre hemos tenido dos puntos únicos de entrada, en estos puntos de entrada podemos incluir las clases necesarias, realizar labores de levantamiento, etc.
En un ambiente en Web es igual de necesario tener un punto de entrada único en nuestra aplicación, así podemos controlar y definir la configuración de nuestra base de datos, que templates vamos a usar, logs, etc.
Aquí podemos ver la utilidad de manejar un punto central de carga, ahora en un ambiente web luego es complicado llegar a esta automatización, y otros lenguajes proveen algunas herramientas para facilitar esto (por ejemplo en ASP tenemos el global.asa, etc.).
Un FrontController es como la operadora de teléfonos que esta en la central que se encargaba en tiempos antiguos de conectar las llamadas entre extensiones, para recordarnos les dejo esta foto:

Esa precisamente es la tarea del FrontController, escucha las peticiones que vienen desde un URL, y se encarga de hacer un dispatch al controlador especifico que mandemos llamar, posteriormente llama a la acción deseada de nuestro controlador, en pocas palabras es un Router de requests, y tiene la facilidad de que al todo ser centralizado podemos hacer tareas de levantamiento.
Un ejemplo sencillo de aplicar este patrón seria el siguiente:
1 2 class FrontController {
3 public static function Main() {
4 // Realizamos tareas antes de iniciar el proceso, aqui podemos iniciar lo que sea relativamente...
5 $config = new ConfigBag();
6 $config['db'] = new ConfigBag();
7 $config['db']['host'] = "localhost";
8 $config['db']['user'] = "usuarioDB";
9 $config['db']['password'] = "pass";
10 $config['db']['database'] = "proyecto";
11
12 DB::setDefaultConfig( $config['db'] );
13 ActiveTable::setDefaultDBAdapter( DB::getInstance() );
14
15 $logFile = "/path/a/log/log.log";
16 Logger::setDefaultLogger( new FileLogger( $logFile ) );
17
18 // Definimos nuestro directorio de Controllers
19 $controllerDir = "/path/a/los/controllers/";
20 // Obtenemos el controlador y la accion
21 $controller = $_GET['controller'];
22 $accion = $_GET['accion'];
23
24 if( empty( $controller ) ) { // Comprobamos si esta vacia, si asi es definimos que por defecto cargue Index
25 $controller = "index";
26 }
27 if( empty( $accion ) ) { // Comprobamos tambien..
28 $accion = "index";
29 }
30
31 $controllerFile = $controllerDir . $controller . ".php";
32 if( !file_exists( $controllerFile ) ) { // Si no existe el archivo lanzamos una excepcion
33 throw new FrontControllerException( "No se encontro el archivo especificado" );
34 }
35
36 $controllerClass = $controller . "Controller";
37 if( class_exists( $controllerClass, false ) ) { // Si existe el archivo pero no esta la clase lanzamos otra excepcion
38 throw new FrontControllerException( "El controlador fue cargado pero no se encontro la clase" );
39 }
40
41 $controllerInst = new $controllerClass();
42
43 if( !is_callable( array( $controllerInst, $accion ) ) ) { // Comprobamos si la accion es posible llamarla
44 throw new FrontControllerException( "El controlador no tiene definida la accion $accion" );
45 } else {
46 $controllerInst->$accion(); // Llamamos a la accion y dejamos el proceso al controlador
47 }
48 }
49 }
50
51 class FrontControllerException extends Exception {}
52
53 // Iniciamos todo
54 FrontController::Main();
55 ?>
Como podemos ver el FrontController es un Router que se encarga de enrutar las peticiones, para que esto sea centralizado tenemos que forzosamente llamar al router ej:
http://host/router.php?controller=automoviles&accion=listaAutomoviles
Ahora con la facilidad que nos da mod_rewrite podemos crear reglas para que nos transforme ese url en algo mas amigable:
http://host/automoviles/listaAutomoviles/
Asi podemos pasar los parametros de forma oculta, un ejemplo de esta regla seria:
RewriteRule ^(.+)/(.+)/$ router.php?controller=$1&action=$2
Las demas acciones que levanta el FrontController son de ejemplo, asi que podemos ver como centralizar la carga de nuestras clases, en un solo archivo, los includes los podemos realizar de igual manera en nuestros controladores especificando el path completo.
Es todo por hoy y espero les sea claro.
Saludos.
