Skip to content

2. Un enfoque de desarrollo MVC en web/PHP

Aquí proponemos un enfoque para el desarrollo de aplicaciones web/PHP que respeten la arquitectura MVC. Este enfoque solo pretende abrir nuevas posibilidades. El lector lo adaptará a sus preferencias y necesidades.

  1. Comenzaremos por definir todas las vistas de la aplicación. Estas son las páginas web que se le presentan al usuario. Nos pondremos en su lugar para diseñar las vistas. Se distinguen tres tipos de vistas:
    • el formulario de entrada, cuyo objetivo es obtener información del usuario. Por lo general, cuenta con un botón para enviar al servidor la información ingresada.
    • la página de respuesta, que solo sirve para proporcionar información al usuario. Esta suele contar con uno o varios enlaces que permiten al usuario continuar con la aplicación en otra página.
    • la página mixta: el controlador envió al cliente una página que contiene información generada por él. Esa misma página servirá al cliente para proporcionar al controlador nueva información proveniente del usuario.
  1. Cada vista generará una página PHP. Para cada una de ellas:
    • se definirá el aspecto de la página
    • se determinarán cuáles son las partes dinámicas de la misma:
      • la información destinada al usuario que deberá proporcionar el controlador como parámetros a la vista PHP. Una solución sencilla es la siguiente:
        • el controlador coloca en un diccionario $dReponse la información que desea proporcionar a una vista V
        • el controlador muestra la vista V. Si esta corresponde al archivo fuente V.php, esta visualización se obtiene simplemente mediante la instrucción include V.php.
        • La inclusión anterior es una inclusión de código en el controlador. Se puede acceder directamente al diccionario $dReponse, que este ha completado, mediante el código de V.php.
      • Los datos de entrada que deberán transmitirse al programa principal para su procesamiento. Estos deberán formar parte de un formulario HTML (etiqueta <form>).
  1. Se pueden esquematizar las entradas y salidas de cada vista
  • las entradas son los datos que el controlador deberá proporcionar a la página PHP
  • las salidas son los datos que deberá proporcionar la página PHP al controlador de la aplicación. Estas forman parte de un formulario HTML y el controlador las recuperará mediante una operación del tipo $_GET["param"] (método GET) o $_POST["param"] (método POST).
  1. Con frecuencia, la página final enviada al cliente no es una vista, sino una composición de vistas. Por ejemplo, la página enviada a un usuario puede tener la siguiente forma:

El área 1 puede ser un banner de título, el área 2 un banner de menú y el área 3 un área de contenido. En PHP, esta composición se puede obtener mediante el siguiente código 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>

Se puede hacer que este código sea dinámico escribiendo:

<table>
    <tr>
        <td><?php include $dReponse['urlZone1'] ?></td>
    </tr>
    <tr>
        <td><?php include $dReponse['urlZone2'] ?></td>
        <td><?php include $dReponse['urlZone3'] ?></td>
    </tr>
</table>

Esta composición de vistas puede ser el único formato de la respuesta que se le da al usuario. En este caso, cada respuesta al cliente deberá establecer los tres URL que se cargarán en las tres zonas antes de mostrar la página de respuesta. Se puede generalizar este ejemplo imaginando que existen varios modelos posibles para la página de respuesta. Por lo tanto, la respuesta al cliente deberá:

  • especificar el modelo que se utilizará
  • especificar los elementos que se incluirán en él
  • solicitar la visualización del modelo
  1. Se escribirá el código PHP/HTML de cada modelo de respuesta. Su código suele ser sencillo. El del ejemplo anterior podría ser:
<?php
    // inicializaciones para pruebas sin controlador
...
?>
<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>

Siempre que sea posible, se utilizará una hoja de estilo para poder cambiar el «aspecto» de la respuesta sin tener que modificar el código PHP/HTML.

  1. Se escribirá el código PHP/HTML de cada vista elemental. Por lo general, tendrá la siguiente forma:
<?php
     // posiblemente algunas inicializaciones, especialmente en la fase de depuración
    ...
?>

<balise>
...
         // aquí se buscará minimizar el código PHP
</balise>

Cabe señalar que una vista elemental se integra en un modelo. Su código HTML se integra dentro del código de este último. Por lo general, este último ya incluye las etiquetas <html>, <head> y <body>. Por lo tanto, es poco frecuente encontrar estas etiquetas en una vista elemental.

  1. Se pueden realizar pruebas de los diferentes modelos de respuesta y vistas elementales
  • Se prueba cada modelo de respuesta. Si un modelo se llama modele1.php, se solicitará desde un navegador el URL http://localhost/chemin/modele1.php. El modelo espera valores del controlador. Aquí se llama directamente y no a través del controlador. El modelo no recibirá los parámetros esperados. Para que las pruebas sean posibles de todos modos, se inicializarán manualmente, con constantes, los parámetros esperados en la página PHP del modelo.
  • Se prueba cada modelo, así como todas las vistas elementales. Este es también el momento de elaborar los primeros elementos de las hojas de estilo que se utilizarán.
  1. A continuación, se escribe la lógica de la aplicación:
  • El controlador o programa principal suele gestionar varias acciones. Es necesario que en las solicitudes que le llegan se defina la acción que se debe realizar. Esto se puede hacer mediante un parámetro de la solicitud que aquí llamaremos «acción»:
    • si la solicitud proviene de un formulario (<form>), este parámetro puede ser un parámetro oculto del formulario:
<form ... action="/C/main.php" method="post"  ...>
<input type="hidden" name="action" value="uneAction">
...
</form>
  • (continuación)
    • Si la solicitud proviene de un enlace, se puede configurar este:
 <a href="/C/main.php?action=uneAction">lien</a>

El controlador puede comenzar por leer el valor de este parámetro y luego delegar el procesamiento de la solicitud a un módulo encargado de manejar este tipo de solicitud. Aquí hemos considerado el caso en el que todo se controla mediante un único script llamado main.php. Si la aplicación debe procesar acciones como acción1, acción2, ..., actionx, se puede crear dentro del controlador una función por cada acción. Si hay muchas acciones, se puede llegar a tener un controlador «dinosaurio». También se pueden crear scripts action1.php, action2.php, ...,actionx.php encargados de procesar cada una de las acciones. El controlador que deba procesar la acción actionx simplemente cargará el código del script correspondiente mediante una instrucción del tipo include "actionx.php". La ventaja de este método es que se trabaja fuera del código del controlador. De esta manera, cada miembro del equipo de desarrollo puede trabajar en el script de procesamiento de una acción «actionx» de manera relativamente independiente. La inclusión del código del script actionx.php en el código del controlador en el momento de la ejecución también tiene la ventaja de aligerar el código cargado en memoria. Solo se carga el código de procesamiento de la acción en curso. Esta inclusión de código hace que las variables del controlador puedan entrar en conflicto con las del script de la acción. Veremos que podemos asegurarnos de limitar las variables del controlador a unas pocas variables bien definidas, que luego habrá que evitar usar en los scripts.

  • Buscamos sistemáticamente aislar el código de negocio o el código de acceso a los datos persistentes en módulos separados. El controlador es una especie de jefe de equipo que recibe solicitudes de sus clientes (usuarios web) y las hace ejecutar por las personas más adecuadas (los módulos de negocio). Al escribir el controlador, se determinará la interfaz de los módulos de negocio que se deben desarrollar. Esto, en caso de que dichos módulos de negocio deban crearse. Si ya existen, entonces el controlador se adaptará a la interfaz de esos módulos existentes.
  1. Se escribirá el esqueleto de los módulos de negocio necesarios para el controlador. Por ejemplo, si este utiliza un módulo getCodes que devuelve una tabla de cadenas de caracteres, en un primer momento basta con escribir:
function getCodes(){
    return array("code1","code2","code3");
}
  1. A continuación, se puede pasar a las pruebas del controlador y de los scripts PHP asociados:
  • el controlador, los scripts de acciones, los modelos, las vistas y los recursos necesarios para la aplicación (imágenes, etc.) se colocan en la carpeta DC asociada al contexto C de la aplicación.
  • Una vez hecho esto, se prueba la aplicación y se corrigen los primeros errores. Si main.php es el controlador y C el contexto de la aplicación, se solicitará el URL http://localhost/C/main.php. Al final de esta fase, la arquitectura de la aplicación está operativa. Esta fase de prueba puede resultar complicada, ya que se cuenta con pocas herramientas de depuración si no se utilizan entornos de desarrollo avanzados, que por lo general son de pago. Podemos recurrir a las instrucciones echo "mensaje", que escriben en el flujo HTML enviado al cliente y, por lo tanto, aparecen en la página web que muestra el navegador.
  1. Finalmente, se escriben las clases de negocio que necesita el controlador. Aquí se trata, por lo general, del desarrollo clásico de una clase PHP, que suele ser independiente de cualquier aplicación web. En primer lugar, se probará fuera de este entorno, por ejemplo, con una aplicación de consola. Una vez escrita una clase de negocio, se integra en la arquitectura de implementación de la aplicación web y se comprueba su correcta integración. Se procederá de esta manera para cada clase de negocio.