You are on page 1of 17

Introducción al modelo MVC

Por: Ing. Pedro García Guerrero

Verificamos que este


en ejecución los
servidores apache y
postgresql (usaremos
bitnami WAPP) e
iniciamos sesión en la
página de
http://127.0.0.1/php
pgadmin/
user= postgres
clave = ????

Primero debemos
tener la tabla libros en
la base de datos
postgres:

Definimos los campos

1|Página
Abrimos una ventana
de SQL, para ejecutar
4 comandos INSERT y
tener la tabla con
datos:

En el directorio público del servidor web creamos la carpeta biblioteca, quedando la siguiente
ruta:

C:\Bitnami\wappstack-5.6.30-0\apache2\htdocs\biblioteca

Dentro de este directorio crearemos todos nuestros archivos. El siguiente programa se conecta a
una base de datos, extrae información y la muestra en la página.

index.php
<?php
// Conectar con la base de datos y seleccionarla
$conexion = pg_connect("host=localhost dbname=postgres user=postgres
password=Aeiou_123");
// Ejecutar la consulta SQL
$resultado = pg_query('SELECT libro_id, titulo_tx, disponibles_n FROM libros');
?>

<html>
<head>
<meta charset="utf-8">
<title>Listado de Libros</title>
</head>
<body>
<h1>Listado de Libros</h1>
<table border>
<tr><th>ID</th><th>Titulo</th><th>Disponibles</th></tr>
<?php
// Mostrar los resultados con HTML
while ($fila = pg_fetch_array($resultado, null, PGSQL_ASSOC))
{
echo "\t<tr>\n";
printf("\t\t<td> %s </td>\n", $fila['libro_id']);
printf("\t\t<td> %s </td>\n", $fila['titulo_tx']);
printf("\t\t<td> %s </td>\n", $fila['disponibles_n']);
echo "\t</tr>\n";
}
?>
</table>
</body>
</html>

2|Página
<?php
// Liberando el conjunto de resultados
pg_free_result($resultado);
// Cerrando la conexión
pg_close($conexion);
?>

La salida será:

El script anterior tiene las siguientes desventajas:

 No existe protección frente a errores (¿qué ocurre si falla la conexión con la base de
datos?).
 El código HTML y el código PHP están mezclados en el mismo archivo e incluso en algunas
partes están entrelazados.
 El código solo funciona si la base de datos es postgreSQL.

Diagrama:

Internet index.php
postgreSQL

postgres.libros

3|Página
Separando la presentación
El código va a ser dividido en dos partes. En primer lugar, el código PHP puro con toda la lógica de
negocio se incluye en el script del controlador, como se muestra en el listado:

Index2.php
<?php
// Conectar con la base de datos y seleccionarla
$conexion = pg_connect("host=localhost dbname=postgres
user=postgres password=Aeiou_123");
// Ejecutar la consulta SQL
$resultado = pg_query('SELECT libro_id, titulo_tx, disponibles_n FROM libros');

// Crear el array de elementos para la capa de la vista


$libros = array();
while ($fila = pg_fetch_array($resultado, null, PGSQL_ASSOC)) {
$libros[] = $fila;
}

// Liberando el conjunto de resultados


pg_free_result($resultado);
// Cerrando la conexión
pg_close($conexion);

// Incluir la lógica de la vista


require('vista.php');

El código HTML, que contiene cierto código PHP a modo de plantilla, se almacena en el script
de la vista, como se muestra a continuación:

vista.php
<html>
<head>
<meta charset="utf-8">
<title>Listado de Libros</title>
</head>
<body>
<h1>Listado de Libros</h1>
<table border>
<tr><th>ID</th><th>Titulo</th><th>Disponibles</th></tr>
<?php foreach ($libros as $libro): ?>
<tr>
<td> <?php echo $libro['libro_id'] ?> </td>
<td> <?php echo $libro['titulo_tx'] ?> </td>
<td> <?php echo $libro['disponibles_n'] ?> </td>
</tr>
<?php endforeach; ?>
</table>
</body>
</html>

Una buena regla general para determinar si la parte de la vista está suficientemente limpia de
código es que debería contener una cantidad mínima de código PHP, la suficiente como para que
un diseñador HTML sin conocimientos de PHP pueda entenderla.

Las instrucciones más comunes en la parte de la vista suelen ser echo, if / endif, foreach /
endforeach y poco más.

Además, no se deben incluir instrucciones PHP que generen etiquetas HTML.

4|Página
Toda la lógica se ha centralizado en el script del controlador, que solamente contiene código PHP y
ningún tipo de HTML.

De hecho, y como puedes imaginar, el mismo controlador se puede reutilizar para otros tipos de
presentaciones completamente diferentes, como por ejemplo un archivo PDF o una estructura de
tipo XML.

Diagrama:

postgreSQL
Internet index2.php
postgres.libro

vista.php

5|Página
Separando la manipulación de los datos
¿Qué ocurre si cambia el modelo de datos y la tabla artículo pasa a llamarse libros?

¿Y si se quiere cambiar a Oracle en vez de PostgreSQL?

Para poder hacer todo esto, es imprescindible eliminar del controlador todo el código que se
encarga de la manipulación de los datos y ponerlo en otro script, llamado el modelo, tal y como se
muestra:

modelo.php
<?php
function getTodosLosLibros()
{
// Conectar con la base de datos y seleccionarla
$conexion = pg_connect("host=localhost dbname=postgres
user=postgres password=Aeiou_123");
// Ejecutar la consulta SQL
$resultado = pg_query('SELECT libro_id, titulo_tx, disponibles_n FROM libros');

// Crear el array de elementos para la capa de la vista


$libros = array();
while ($fila = pg_fetch_array($resultado, null, PGSQL_ASSOC)) {
$libros[] = $fila;
}

// Liberando el conjunto de resultados


pg_free_result($resultado);
// Cerrando la conexión
pg_close($conexion);
return $libros;
}
?>

El controlador modificado se puede ver a continuación:

index3.php
<?php
// Incluir la lógica del modelo
require_once('modelo.php');

// Obtener la lista de artículos


$libros = getTodosLosLibros();

// Incluir la lógica de la vista


require('vista.php');
?>

Ahora el controlador es mucho más fácil de leer.

Su única tarea es la de obtener los datos del modelo y pasárselos a la vista.

En las aplicaciones más complejas, el controlador se encarga además de procesar las peticiones,
las sesiones de los usuarios, la autenticación, etc.

El script del modelo solamente se encarga del acceso a los datos y puede ser reorganizado a tal
efecto.

6|Página
Todos los parámetros que no dependen de la capa de datos (como por ejemplo los parámetros de
la petición del usuario) se deben obtener a través del controlador y por tanto, no se puede
acceder a ellos directamente desde el modelo.

Las funciones del modelo se pueden reutilizar fácilmente en otros controladores.

Diagrama:

modelo.php postgreSQL

postgres.libro

Internet index3.php Este es el famoso


controlador!

vista.php

Conclusión:
MVC (Modelo-Vista-Controlador)
El principio más importante de la arquitectura MVC es la separación del código del programa en
tres capas, dependiendo de su naturaleza:

 La lógica relacionada con los datos se incluye en el MODELO,

 el código de la presentación en la VISTA y

 la lógica de la aplicación en el CONTROLADOR.

7|Página
Separación en capas más allá del MVC
La programación se puede simplificar si se utilizan otros patrones de diseño. De esta forma, las
capas del modelo, la vista y el controlador se pueden subdividir en más capas.

Patrones de Diseño. "Cada


patrón describe un problema
que ocurre infinidad de veces
en nuestro entorno, así como la
solución al mismo, de tal modo
que podemos utilizar esta
solución un millón de veces
más adelante sin tener que
volver a pensarla otra vez."

Abstracción de la base de datos


La capa del modelo se puede dividir en la capa de acceso a los datos y en la capa de abstracción de
la base de datos.

Objetivo: Independizar sentencias y consultas del DBMS.

Ventaja: Si cambia de DBMS, solamente actualiza la capa de abstracción de la base de datos.

Ejemplo de capa de acceso a datos específica para MySQL:

conector_mysql.php
<?php

function crear_conexion($servidor, $usuario, $contrasena)


{ // Conectar con la base de datos
$conexion = mysql_connect($servidor, $usuario, $contrasena);
return $conexion;
}

function cerrar_conexion($conexion)
{ // Cerrar la conexión
mysql_close($conexion);
}

function consulta($consulta,$base_datos,$conexion)
{ mysql_select_db($base_datos, $conexion);
// Ejecutar la consulta SQL
$resultado = mysql_query($consulta, $conexion);
return $resultado;
}

function obtener_registro($resultado)
{ $fila = mysql_fetch_array($resultado, MYSQL_ASSOC);
return $fila;
}

8|Página
Ejemplo de capa de acceso a datos específica para postgreSQL:

conector_postgresql.php
<?php
function crear_conexion($servidor, $bd, $usuario, $contrasena)
{ // Conectar con la base de datos y seleccionarla
$conexion = pg_connect("host=$servidor dbname=$bd user=$usuario password=$contrasena");
return $conexion;
}

function cerrar_conexion($conexion)
{ // Liberando el conjunto de resultados
pg_free_result($resultado);
// Cerrando la conexión
pg_close($conexion);
return $libros;
}

function consulta($conexion, $consulta)


{ // Ejecutar la consulta SQL
$resultado = pg_query($conexion, $consulta);
return $resultado;
}

function obtener_registro($resultado)
{ $fila = pg_fetch_array($resultado, null, PGSQL_ASSOC);
return $fila;
}
?>

Ejemplo de capa de abstracción de la base de datos:

modelo2.php
<?php
function getTodosLosLibros()
{ // Conectar con la base de datos y seleccionarla
$conexion = crear_conexion("localhost", "postgres", "postgres", "Aeiou_123");

// Ejecutar la consulta SQL


$resultado = consulta($conexion, 'SELECT libro_id, titulo_tx, disponibles_n FROM
libros');

// Crear el array de elementos para la capa de la vista


$libros = array();
while ($fila = obtener_registro($resultado)) {
$libros[] = $fila;
}

// Cerrando la conexión
cerrar_conexion($conexion);
return $libros;
}
?>

9|Página
Y modificamos ligeramente el index…

Index4.php
<?php
// Incluir la conexión al DBMS
require_once('conector_postgresql.php');

// Incluir la lógica del modelo


require_once('modelo2.php');

// Obtener la lista de artículos


$libros = getTodosLosLibros();

// Incluir la lógica de la vista


require('vista.php');
?>

Diagrama:

Conector
postgreSQL
postgresql.php
postgres.libro

modelo2.php

Internet Index4.php

vista.php

10 | P á g i n a
Los elementos de la vista
Las páginas web suelen contener elementos que se muestran de forma idéntica a lo largo de toda
la aplicación:

 cabeceras de la página,
 el layout genérico,
 el pie de página y
 la navegación global.

Normalmente sólo cambia el interior de la página. Por este motivo, la vista se separa en un layout
y en un contenido.

Normalmente, el layout es global en toda la aplicación o al menos en un grupo de páginas.

El contenido sólo se encarga de visualizar las variables definidas en el controlador.

Para que estos componentes interaccionen entre sí correctamente, es necesario añadir cierto
código.

Siguiendo estos principios, la parte de la vista se puede separar en tres partes:

 Contenido (contenido.php)
 Lógica de la vista (lógica_vista.php)
 Layout (layout.php)

A continuación se muestra el código:

contenido.php
<h1>Listado de Libros (Mi plantilla)</h1>
<table border>
<tr><th>ID</th><th>Titulo</th><th>Disponibles</th></tr>
<?php foreach ($libros as $libro): ?>
<tr>
<td> <?php echo $libro['libro_id'] ?> </td>
<td> <?php echo $libro['titulo_tx'] ?> </td>
<td> <?php echo $libro['disponibles_n'] ?> </td>
</tr>
<?php endforeach; ?>
</table>

lógica_vista.php
<?php
//Parte de la lógica
$titulo = 'Listado de Libros (lógica de la vista)';

// La función ob_start() sirve para guardar la salida en


// un bufer interno, en vez de enviarla al cliente.
ob_start();
include('contenido.php') ;

// Obtiene el contenido del búfer actual y elimina el búfer


// de salida actual.
$contenido=ob_get_clean();
?>

11 | P á g i n a
layout.php
<html>
<head>
<meta charset="utf-8">
<title><?php echo $titulo ?></title>
</head>
<body>
<!--- Encabezado de la página -->
<div class="encabezado" style="height:15%; background-color: gray;">
<h1>Librería Ardilla </h1>
</div>

<div class="contenido" style="height:70%;">


<?php echo $contenido; ?>
</div>
<!--- Pie de página -->
<div class="pie" style="height:10%; background-color: gray;">
<cite>Introducción al MVC. ITSLP 2017</cite><br/>
<cite>Por: Ing. Pedro García Guerrero</cite>
</div>
</body>
</html>

Y nuevamente modificamos ligeramente el index…

Index5.php
<?php
// Incluir la conexión al DBMS
require_once('conector_postgresql.php');

// Incluir la lógica del modelo


require_once('modelo2.php');

// Obtener la lista de artículos


$libros = getTodosLosLibros();

// Incluir la lógica de la vista


require('logica_vista.php');
require('layout.php');
?>

Y obtenemos:

12 | P á g i n a
Diagrama:

conector_
postgreSQL
mysql.php
postgres.libro
s

modelo2.php

Internet index5.php

logica_vista.php

layout.php contenido.php

13 | P á g i n a
Mejorando la vista usando un framework
CSS (Bulma)
Usaremos hojas de estilo para mejorar la apariencia de la página, pero para hacerlo con poco
esfuerzo se pueden usar librerías CSS de terceros como:

 Bootstrap
 Pure
 Mini
 Bulma

En este caso usaremos Bulma (bulma.io):

A continuación se muestra el código en cada uno de los archivos para incluir los cambios de estilo:

contenido2.php
<h3 class="subtitle is-4">Listado de Libros (Mi plantilla)</h3>
<table class="table">
<tr><th>ID</th><th>Titulo</th><th>Disponibles</th></tr>
<?php foreach ($libros as $libro): ?>
<tr>
<td> <?php echo $libro['libro_id'] ?> </td>
<td> <?php echo $libro['titulo_tx'] ?> </td>
<td> <?php echo $libro['disponibles_n'] ?> </td>
</tr>
<?php endforeach; ?>
</table>

14 | P á g i n a
Layout2.php
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?php echo $titulo ?></title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-
awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.5.0/css/bulma.min.css">

<style media="screen">
.hero { background-color: #ffe6e6;
}
.footer { background-color: #ffe6e6;
}
</style>
</head>

<body>
<div class="container is-desktop">
<!--- Encabezado de la página -->
<section class="hero">
<div class="hero-body">
<div class="container">
<h1 class="title">
Librería Ardilla
</h1>
<h2 class="subtitle">
Ejemplo del Modelo-Vista-Controlador
</h2>
</div>
</div>
</section>

<!--- Contenido -->


<div class="contenido" style="height:40%;">
<?php echo $contenido; ?>
</div>

<!--- Pie de página -->


<footer class="footer">
<div class="container">
<div class="content has-text-centered">
<p>
Introducción al MVC.<br/>
<strong>ITSLP 2017</strong> <br/>
<cite>Por: Ing. Pedro García Guerrero</cite> <br/>
<img width="200 px" class="icon"
src="https://pbs.twimg.com/profile_images/2586957490/htb5w3ks6peur4edplw1_400x400.png">
</img>
</p>
</div>
</div>
</footer>

</div>
</body>
</html>

15 | P á g i n a
Y nuevamente modificamos ligeramente el index…

Index6.php
<?php
// Incluir la conexión al DBMS
require_once('conector_postgresql.php');

// Incluir la lógica del modelo


require_once('modelo2.php');

// Obtener la lista de artículos


$libros = getTodosLosLibros();

// Incluir la lógica de la vista


require('logica_vista.php');
require('layout2.php');
?>

Finalmente obtenemos:

16 | P á g i n a
Diagrama:

conector_
postgreSQL
mysql.php
postgres.libro
s

modelo2.php

Internet index5.php

logica_vista.php

layout.php contenido.php

Framework CSS

BULMA

17 | P á g i n a

You might also like