MVC (Modelo Vista Controlador) en PHP nativo

En este tutorial sobre el uso del MVC en PHP veremos de forma simple y clara que es el MVC, como funciona y como se implementa en PHP nativo sin frameworks.

¿Que es el patrón MVC?

El patrón de diseño (de software) MVC se encarga de separar la lógica de negocio de la interfaz de usuario y es el mas utilizado en aplicaciones web, framework, etc, ya que facilita la funcionalidad, mantenibilidad, y escalabilidad del sistema, de forma comoda y sencilla, a la vez que ayuda no mezclar lenguajes de programación en el mismo código, el conocido “código espagueti”.
MVC divide las aplicaciones en tres niveles de abstracción:

  1. Modelo: es la lógica de negocios. Es decir las clases y métodos que se comunican directamente con la base de datos.
  2. Vista: es la encargada de mostrar la información al usuario, con de forma gráfica y legible.
  3. Controlador: el intermediario entre la vista y el modelo, se encarga de controlar las interacciones del usuario en la vista, pide los datos al modelo y los devuelve de nuevo a la vista para que esta los muestre al usuario. Es decir las llamadas a clases y métodos, y los datos recibidos de formularios.

¿Como funciona el MVC?

El funcionamiento básico del patrón MVC, puede resumirse en:

  1. El usuario realiza una petición.
  2. El controlador captura la petición.
  3. Hace la llamada al modelo correspondiente.
  4. El modelo sera el encargado de interactuar con la base de datos.
  5. El controlador recibe la información y la enviá a la vista.
  6. La vista muestra la información.

Esquema muy claro del funcionamiento del MVC en PHP de phpzag.com
mvc-php

¿Como implementar el MVC en PHP?

Para implementar el MVC es imprescindible crear una estructura de ficheros parecida a esta:
Estructura de directorios MVC

Veamos un ejemplo típico del uso del MVC con PHP. Para comprenderlo seria ideal que supieras PHP Orientado a objetos y como funciona la extensión MySQLi

# index.php

<?php
require_once("db/db.php");
require_once("controllers/personas_controller.php");
?>

# db.php

<?php
class Conectar{
	public static function conexion(){
		$conexion=new mysqli("localhost", "root", "", "mvc");
		$conexion->query("SET NAMES 'utf8'");
		return $conexion;
	}
}
?>

# model/personas_model.php

<?php
class personas_model{
	private $db;
	private $personas;

	public function __construct(){
		$this->db=Conectar::conexion();
		$this->personas=array();
	}
	public function get_personas(){
		$consulta=$this->db->query("select * from personas;");
		while($filas=$consulta->fetch_assoc()){
			$this->personas[]=$filas;
		}
		return $this->personas;
	}
}
?>

# contoller/personas_controller.php

<?php
//Llamada al modelo
require_once("models/personas_model.php");
$per=new personas_model();
$datos=$per->get_personas();

//Llamada a la vista
require_once("views/personas_view.phtml");
?>

El controlador debe tener siempre esta estructura llamada al modelo y debajo a la vista, si hubiera mas modelos y vistas se sigue haciendo así con todos.

# view/personas_view.phtml

<!DOCTYPE html>
<html lang="es">
	<head>
		<meta charset="UTF-8" />
		<title>Personas</title>
	</head>
	<body>
		<?php
			foreach ($datos as $dato) {
				echo $dato["nombre"]."<br/>";
			}
		?>
	</body>
</html>

Los ficheros de la vista según el estándar de Zend Framework debemos usar .phtml, pero se podría sin ningún problema usar la extensión .php
Muchos dicen que es recomendable usar CamelCase en los nombres de los ficheros y las clases, a efectos prácticos da igual usarlo que no, incluso algunos frameworks como Codeigniter nos sugieren que usemos nombres como «wellcome_model» por eso no he utilizado CamelCase. Si puedes y quieres abusa del CamelCase, porque así lo dicen los estándares.

Esquema del ejemplo:
Esquema del ejemplo MVC

A partir de aquí ya sabemos se podría implementar un controlador frontal que cargue un controlador u otro en función de la url, etc, pero eso lo veremos en próximos capítulos. Mientras tanto puedes aprender mas sobre PHP, el MVC y los frameworks en mi curso gratuito de introducción a los framworks para PHP.

Víctor Robles WEB

Autor: Victor

Desarrollador web - Formador online - Blogger

Compartir este post

32 Comentarios

  1. me ha gustado tu post, quiero hacer una aplicación pero como es tan pequeña y la tengo que terminar en tan poco tiempo pss aprender un framework no me va a dar el tiempo, pero tampoco quiero hacer todo a la vieja manera gracias por tu post..!

    Responder
  2. Hola amigo gracias por compartir lo que sabes, tengo una duda ya me sale toda la informacion pero si quisiera captar un datos y validarlo y despues mandarlo a la vista ??

    por ejemplo tu imprimes nombre ya en vista pero si desde el modelo quisiera validarlo y despues mandarlo a vista como lo podria hacer??

    mi ejemplo es: de la tabla traigo una columna que es status (1 ,2 ,3 o 0) y quisiera usar un while con case para verificar si es 1 cambiarlo a Nuevo, si es 2 cambiarlo a aprovar y asi sucesivamente …. como capto ese dato y despues lo envio a mi vista

    de antemano gracias

    Responder
    • Te haces un método en el modelo, luego instancias el modelo en el controlador, llamas a ese método, ese método ya te devolverá el resultSet y lo guardas en una variable en el controlador, por ejemplo $resultSet=$miModelo->miMétodo(); y esa variable ya está disponible en la vista para hacer lo que quieras con ella.

      Responder
  3. Muy bien explicado.
    He buscado por todos lados un ejemplo pràctico que explique bien del patròn MVC y viendo tantos frameworks dando vueltas por toda la web no he encontrado a alguien que explicara y ponga en pràctica un ejemplo.

    Gracias!.-

    Responder
  4. Gracias por el ejemplo Victor.

    Me queda una duda, en el modelo recorres la consulta para guardar los datos en un arreglo y luego en la vista recorres ese arreglo para mostrar los datos … no es hacer doble trabajo ??.

    No sería mejor llevar el set de datos desde el modelo hasta la vista y solo recorrerlos una vez.

    Responder
    • Efectivamente, es hacer doble trabajo, lo suyo es pasar el resultset a la vista directamente.

      Responder
  5. Hola, la verdad muy buena explicación….Felicidades!!! sigo practicando … 🙁

    Responder
    • Muchas gracias Luis, sigue practicando, la persistencia es el secreto para conseguir tus objetivos 😉

      Responder
  6. Victor , muchas gracias!
    tu claridad y practicidad son la aguja en el pajar de internet.
    GRACIAS!

    Responder
  7. El mejor post de usar MVC con php tradicional (Nativo) … Brutal , saludos desde Venezuela

    Responder
  8. Hola que tal, gracias, al fin comprendi la idea del MVC

    Tengo una duda, mostrar los datos la vista como en tu ejemplo no hay problema, pero si quiero tener digamos una vista principal, y poner los datos de la consulta en otra no se vista2.php, puse el mismo codigo y cambie la ruta de la llamada a la vista para que apunten a vista2.php mas sin embargo sale el error.

    Notice: Undefined variable
    Warning: Invalid argument supplied for foreach()

    gracias.

    Responder
  9. Gracias Victor por transferir ese conocimiento tecnológico.

    Aplica para los proyecto que se quiere utilizar el MVC sin requerir el resto de librerías que trae un Framework, o que las librerías las incluya manualmente.

    Responder
  10. Gracias por la explicación! Gracias!!!

    Responder
  11. Muchísimas gracias! Muy útil, pocos explican tan bien el modelo vista controlador sin usar ningún tipo de framework lleno de librerías que no usamos nunca. Saludos!

    Responder
  12. Muy buena explicación, simple y sencilla, sin tanta arandela. Es lo que estaba buscando.

    Saludos,

    DP.

    Responder
  13. Buenas Victor. Soy un gran seguidor tuyo. Te sigo desde que hice tu primer curso de Slim (después he hecho TypeScript y estoy con angular 2 y symfony 3). He llegado a este articulo a través del curso de symfony 3 (cable SEO) jeje. Bueno quería decirte que creo que lo único que falta en tu código para que quede un poco más claro (si se puede) es usar el patrón Singleton para la conexión con la BD bd.php y crear una clase por ejemplo View (así la llamaba yo) con un metodo render que renderice la plantilla. Esta clase podría ser usada para meterle las varialbes de foma dinámica.
    $view = new View();
    $view->saludo = ‘Hola mundo’;
    return $view->render();

    Responder
  14. Hola Víctor como podrìa hacer una busqueda y resultado en la misma pagina personas_view.phtml?
    gracias

    Responder
  15. Te felicito, Víctor. Por fin he podido comprender el patrón MVC.

    Si vieras el lío que tenía entre clases en mi código spaguetti…

    Menos mal que he encontrado este tutorial, si no sigo cometiendo los mismos errores.

    Gracias de todo corazón.

    Responder
  16. Excelente tutorial, he podido entender un poco mas sobre lo que es la POO, ahora bien me queda el trabajo de seguir indagando para lograr poder implementar mis aplicaciones desarrolladas con programación estructurada. gracias

    Responder
  17. Muchas gracias por este post. Muy bien explicado, me quedó muy claro el concepto.

    Responder
  18. Excelente tu Post! excelente tu canal y tus cursos Victor! Gracias!

    Responder
  19. Eres un grande brother! lo mejor fue comprar el curso de master en php excelente!

    Responder
  20. muy buena explicación del MVC, estoy haciendo un proyecto con PHP y este post me sirve de ayuda.

    Responder
  21. Excelente explicación, gracias!

    Responder
  22. Victor eres una crack

    Responder
  23. Excelente explicación Victor, muchas gracias !!!! 😀

    Responder
  24. Excelente Post gracias por explicar paso a paso este modelo, es importante entender como funciona por debajo el modelo, para entender ya en código su estructura muchas gracias por el conocimiento aprendido.

    Responder
  25. Muy buen aporte, gracias por la explicación.

    Responder
  26. Estoy en el curso de Master en PHP y esta muy claro y sin rodeos, GRACIAS

    Responder
  27. Saludos, muy bueno.

    Responder
  28. Está genial y bien explicado. Tendrias un crud para ver mas cosas. Gracias

    Responder
  29. Gracias por la explicación! Gracias!!!

    Responder

Poner un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *