MVC: Model View Controller

En programación PHP5 usaremos el patrón de diseño MVC Model View Controller
  • modelo: mysql (lógica de negocio y accesos a base de datos)
  • vista: html (diseñadores y maquetadores)
  • controller: php (respuesta a las peticiones del explorador, cargando una vista con los datos obtenidos de un modelo).

El Controlador
  • Se llama desde el navegador
  • Lee el modelo y escribe en la vista
    • un controller puede tener diferentes VISTAS y diferentes MODELS.
  • En el controlador va la codificación / programación del formulario.
    • en el controller pongo include ("formulario.php")
    • en formulario.php quito el action, para que se llame a si mismo
  • Cada archivo que procese un formulario se llamara controler. La acción va a estar dentro del controlador.
    • Encima del controlador irá un switch.... para escoger el tipo de acción.

Vistas
  • Las dividimos en (habrá un layout para cada uno)
    • frontend (parte pública)
    • backend (para usuarios registrados)
  • website wireframe
    • define las vistas
    • cada vista tiene extensión .phtml
  • Un modelo nunca llama a una vista. Es el controlador el que rellena una vista con los datos del modelo.

Model
  • Aqui está el código de todas las funcionalidades
  • Puede haber infinitas lineas, librerías externas (Zend framework)

Estructura de directorios

En C:\
  • /www
    • /proyecto1
      • /public : lo que se verá desde el navegador
        • /styles
          • /css
          • /images: imágenes de background, de listas
        • /scripts
          • /js: javascript
        • /assets
          • /images: imágenes del usuario que suben los usuarios - tiene permiso de ESCRITURA
          • /img: imágenes de mi web (el logo, banners)
          • /swfs: flash
          • /movs; películas (opcional)
        • index.php (este es el BOOTSTRAP)

      • /docs : toda la documentación (el archivo PDF que define el proyecto, la licencia, el modelo de BBDD, y el fichero mysqlworkbench)

      • /library : las rutinas ya inventadas (cargas múltiples de archivos, foros, envío masivo de emails, ... ) que quiero utilizar.
        • /zend : ZEND es la mejor librería PHP (esta carpeta no es necesario tenerla si el servidor tiene instalado Zend Server)
      • /application
        • /configs
          • settings.xml
        • /controllers
        • /layouts
        • /models
          • functions_db.php
        • /modules
          • /modulo1. por ej. usuarios
            • /controllers
              • usuarios.php
            • /models
              • functions_usuarios.php
            • /views
              • modificar_usuarios.phtml 
              • seleccionar_usuarios.phtml
          • /modulo 2
            • /controllers
            • /models
            • /views
        • /views

En Application estarán todos los ficheros de configuración y código que no deba ver un usuario. El solo tendrá acceso directo a public


Bootstrap


Estructura del proyecto en módulos

  • Cada proyecto se debe dividir en módulos que funcionan casi independientemente.
  • Cada módulo tiene estructura MVC con 3 carpetas: controllers, models, views
  • El código debe ser reutilizable: así los módulos pueden usarse en diferentes proyectos
  • Se definen vistas para cada módulo
  • Los módulos puede estar creados por nosotros o pueden ser ya existentes (de Zend, por ejemplo)
  • La home será un módulo frontend que construye la página principal a través de otros módulos.

.htaccess

  • Es un fichero que está en public/ que permite a una URL ser del tipo http://localhost/usuarios/index/id/5
  • Para verlo en Zend Studio: window > show view > navigator
  • El nombre del módulo se usa como namespace para distinguir controladores que tienen el mismo nombre en módulos diferentes..
  • Si en la url dominio.com/modulo/controller/accion en el bootstrap se hará un
    case 'modulo:controlador'



Ejemplo

Formulario

  • En el formulario hay dos botones. Al pulsar cualquiera de los botones se genera un Post al servidor, el cual recoge el controlador (en el ejemplo usuariosdb.php)
  • Lo que se envía al servidor se puede recoger por
    • $_GET: los parámetros que se colocan el la URL (action=Insertar)
    • $_POST: los campos input del formulario, con su name asociado
<h3>Formulario usuario</h3>
<form method="post" action="usuariosdb.php?action=Insertar" enctype="multipart/form-data" >
    <table>
        <tr><td>Nombre: </td><td><input type="text" name="nombre"  size="20" /></td></tr>
        <tr><td>Email: </td><td><input type="text" name="email"  size="20" /></td></tr>
        <tr><td>Password: </td><td><input type="text" name="password"  size="20" /></td></tr>
        <tr><td>Fecha: </td><td><input type="text" name="fecha"  size="20" /></td></tr>
        <tr><td>Status: </td><td>
            <select name="status">
             <option value="1" selected>Activo</option>
             <option value="0">Inactivo</option>
            </select>
        </td></tr>
        <tr><td colspan="2">
            <input type="submit" name="button_action" value="insert" />
            <input type="submit" name="button_action" value="cancel" />
        </td></tr>
    </table>
    <?php
        echo "<p>$mensaje</p>";
    ?>
</form>

Controlador

Todas las acciones de los botones generan una acción hacia el controlador, el cual lo recoje todo
En el controlador
  • primero se comprueba si la url contiene algún parámetro consultando $_GET
  • seguidamente según el tipo de parámetro (en este ejemplo, action), se decide la acción por un switch
    • En el caso Mostrar, se lee en un array todos los usuarios, y se incluye un formulario, que en este caso llevará código PHP incrustado
    • En el caso Insertar, comprobamos el name del botón pulsado que obtenemos con $_POST["nombreBoton"]
      • En caso de que se pulse el botón Insertar, se comprueban los campos, y estos se pasan a una rutina de inserción, y seguidamente una redirección al controlador.
      • Si hay algún campo incorrecto, se genera un mensaje que aparecerá en el formulario, como mensaje.
<?php
echo "<h2>CRUD de tabla de usuarios</h2>";
 
include_once "../application/modules/usuarios/models/user_functions.php";
include_once "../application/configs/dbsettings.php";
include_once "../application/models/dbfunctions.php";
 
//opcion por defecto mostrar
$action = "Mostrar";
 
//parámetros via querystring
if (isset ($_GET['action']))
    $action = $_GET['action'];
 
switch($action)
{
    case "Mostrar":
    {
        //read users from data base
        $usuarios = leerUsuarios();
        //show table filled with users
        include_once '../application/modules/usuarios/views/form_list_users.phtml';
        break;
    }
    case "Insertar":
    {
 
        //check if a button has been pressed
        if(isset($_POST['button_action']))
        {
            $boton = $_POST['button_action'];
            if ($boton == "insert")
            {
                $usuario = array();
                $usuario['name'] = $_POST["nombre"];
                $usuario['email'] = $_POST['email'];
                $usuario['password'] = $_POST['password'];
                $usuario['fecha'] = $_POST['fecha'];
                $usuario['status'] = $_POST['status'];
 
                //compruebo (y limpio) si los campos son correctos
                $usuarioRta = comprobarDatosUsuario($usuario);
                if ($usuarioRta["Resultado"])
                {
                    insertarUsuario($usuarioRta['Usuario']);
                    //saltar a select
                    header("Location: usuariosdb.php");
                }
                else
                {
                    $mensaje = $usuarioRta['Mensaje'];
                    include_once '../application/modules/usuarios/views/form_update_user.phtml';
                }
            }
            else
                //boton cancelar
                header("Location: usuariosdb.php");
        }
        else
        {
            $mensaje = "Introducir valores...";
            //if no button has been pressed >> show insert form
            include_once '../application/modules/usuarios/views/form_update_user.phtml';
        }
        break;
    }
    default:
            break;
}
 
?>