Introducción a MVC con PHP, segunda parte
1 de March, 2008
Al fin aquí está la segunda parte del artículo que empecé hace algunos meses. Espero que les sea de utilidad.
En esta parte, como había comentado, mostraré una mini implementación de mvc basada en el ejemplo de la primera parte del artículo pero con programación orientada a objetos. No explicaré la utilización de clases, descuento que saben herencia y demás, solo me limitaré al mvc y poco mas.
Lecturas recomendadas antes de leer este artículo
Clases y objetos en PHP5
Singleton en wikipedia
Empecemos, ingredientes
La estructura de archivos se mantiene bastante con respecto a nuestro ejemplo anterior, pero ahora cada archivo es una Clase, salvo el index.php y el config.php.
index.php
Será la única entrada de nuestro sistema como en el ejemplo anterior, pero en este caso no realiza otra tarea mas que incluir e iniciar el FrontController.
1 2 3 4 5 6 | < ?php //Incluimos el FrontController require 'libs/FrontController.php'; //Lo iniciamos con su método estático main. FrontController::main(); ?> |
libs/FrontController.php
El FrontController es el que recibe todas las peticiones, incluye algunos ficheros, busca el controlador y llama a la acción que corresponde.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | < ?php class FrontController { static function main() { //Incluimos algunas clases: require 'libs/Config.php'; //de configuracion require 'libs/SPDO.php'; //PDO con singleton require 'libs/View.php'; //Mini motor de plantillas require 'config.php'; //Archivo con configuraciones. //Con el objetivo de no repetir nombre de clases, nuestros controladores //terminaran todos en Controller. Por ej, la clase controladora Items, será ItemsController //Formamos el nombre del Controlador o en su defecto, tomamos que es el IndexController if(! empty($_GET['controlador'])) $controllerName = $_GET['controlador'] . 'Controller'; else $controllerName = "IndexController"; //Lo mismo sucede con las acciones, si no hay accion, tomamos index como accion if(! empty($_GET['accion'])) $actionName = $_GET['accion']; else $actionName = "index"; $controllerPath = $config->get('controllersFolder') . $controllerName . '.php'; //Incluimos el fichero que contiene nuestra clase controladora solicitada if(is_file($controllerPath)) require $controllerPath; else die('El controlador no existe - 404 not found'); //Si no existe la clase que buscamos y su acción, tiramos un error 404 if (is_callable(array($controllerName, $actionName)) == false) { trigger_error ($controllerName . '->' . $actionName . '` no existe', E_USER_NOTICE); return false; } //Si todo esta bien, creamos una instancia del controlador y llamamos a la accion $controller = new $controllerName(); $controller->$actionName(); } } ?> |
libs/View.php
Es una pequeña clase que hace de motor de plantilla, aunque con poquitas funcionalidades. Solo nos permite incluir una plantilla y asignarle variables.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | < ?php class View { function __construct() { } public function show($name, $vars = array()) { //$name es el nombre de nuestra plantilla, por ej, listado.php //$vars es el contenedor de nuestras variables, es un arreglo del tipo llave => valor, opcional. //Traemos una instancia de nuestra clase de configuracion. $config = Config::singleton(); //Armamos la ruta a la plantilla $path = $config->get('viewsFolder') . $name; //Si no existe el fichero en cuestion, tiramos un 404 if (file_exists($path) == false) { trigger_error ('Template `' . $path . '` does not exist.', E_USER_NOTICE); return false; } //Si hay variables para asignar, las pasamos una a una. if(is_array($vars)) { foreach ($vars as $key => $value) { $$key = $value; } } //Finalmente, incluimos la plantilla. include($path); } } /* El uso es bastante sencillo: $vista = new View(); $vista->show('listado.php', array("nombre" => "Juan")); */ ?> |
libs/SPDO.php
SPDO es una clase que extiende de PDO, su única ventaja es que nos permite aplicar el patron Singleton para mantener una única instancia de PDO.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | < ?php class SPDO extends PDO { private static $instance = null; public function __construct() { $config = Config::singleton(); parent::__construct('mysql:host=' . $config->get('dbhost') . ';dbname=' . $config->get('dbname'), $config->get('dbuser'), $config->get('dbpass')); } public static function singleton() { if( self::$instance == null ) { self::$instance = new self(); } return self::$instance; } } ?> |
Models/*Model.php
En el ejemplo anterior los modelos eran ficheros comunes con algunas funciones sueltas, en este caso son clases, y lo que antes eran funciones ahora son métodos. Al igual que en el primer ejemplo, usamos PDO (esta vez a traves de SPDO) para el acceso a datos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | < ?php class ItemsModel { protected $db; public function __construct() { //Traemos la unica instancia de PDO $this->db = SPDO::singleton(); } public function listadoTotal() { //realizamos la consulta de todos los items $consulta = $this->db->prepare('SELECT * FROM items'); $consulta->execute(); //devolvemos la colección para que la vista la presente. return $consulta; } } ?> |
Controllers/*Controller.php
Sucede lo mismo que con los modelos, ahora los controladores son Clases y las acciones son los métodos. La única diferencia con respecto al ejemplo anterior es el uso de la clase View para asignar variables y presentar la plantilla.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | < ?php class ItemsController { function __construct() { //Creamos una instancia de nuestro mini motor de plantillas $this->view = new View(); } public function listar() { //Incluye el modelo que corresponde require 'models/ItemsModel.php'; //Creamos una instancia de nuestro "modelo" $items = new ItemsModel(); //Le pedimos al modelo todos los items $listado = $items->listadoTotal(); //Pasamos a la vista toda la información que se desea representar $data['listado'] = $listado; //Finalmente presentamos nuestra plantilla $this->view->show("listar.php", $data); } public function agregar() { echo 'Aquí incluiremos nuestro formulario para insertar items'; } } ?> |
Views/listar.php
Poco tengo para decir sobre las plantillas, son archivos .php comunes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | < !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>MVC - Modelo, Vista, Controlador - Jourmoly</title> </head> <body> <table> <tr> <th>ID </th><th>Item </th></tr> < ?php // $listado es una variable asignada desde el controlador ItemsController. while($item = $listado->fetch()) { ?> <tr> <td>< ?php echo $item['id_item']?></td> <td>< ?php echo $item['item']?></td> </tr> < ?php } ?> </table> </body> </html> |
libs/Config.php
Es una pequeña clase de configuración con un funcionamiento muy sencillo, implementa el patron singleton para mantener una única instancia y poder acceder a sus valores desde cualquier sitio.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | < ?php class Config { private $vars; private static $instance; private function __construct() { $this->vars = array(); } //Con set vamos guardando nuestras variables. public function set($name, $value) { if(!isset($this->vars[$name])) { $this->vars[$name] = $value; } } //Con get('nombre_de_la_variable') recuperamos un valor. public function get($name) { if(isset($this->vars[$name])) { return $this->vars[$name]; } } public static function singleton() { if (!isset(self::$instance)) { $c = __CLASS__; self::$instance = new $c; } return self::$instance; } } /* Uso: $config = Config::singleton(); $config->set('nombre', 'Federico'); echo $config->get('nombre'); $config2 = Config::singleton(); echo $config2->get('nombre'); */ ?> |
config.php
Es el archivo de configuración, hace uso de una instancia de la clase Config.
1 2 3 4 5 6 7 8 9 10 11 12 | < ?php $config = Config::singleton(); $config->set('controllersFolder', 'controllers/'); $config->set('modelsFolder', 'models/'); $config->set('viewsFolder', 'views/'); $config->set('dbhost', 'localhost'); $config->set('dbname', 'pruebas'); $config->set('dbuser', 'root'); $config->set('dbpass', ''); ?> |
¿Y como funciona todo esto?
Tomando como ejemplo la siguiente URL:
http://www.jourmoly.com.ar/ejemplos/mvc/ejemplo-poo/?controlador=Items&accion=listar
El recorrido detallado es el siguiente:
1. El usuario ingresa por el index.php, aqui se incluye el FrontController y se inicia nuestro sistema.
2. El FrontController incluye los ficheros basicos, averigua el controlador y la acción, incluye el controlador, crea una instancia del mismo y llama a la accion correspondiente. En este caso el controlador es ItemsController y la acción (método) es listar().
3. La acción listar() de ItemsController incluye el modelo que necesita (ItemsModel) y crea una instancia, solicita todos los datos y se los pasa a la instancia de la vista junto con el nombre de la plantilla a presentar (listar.php).
4. La vista incluye la plantilla y asigna las variable $listado.
5. El usuario recibe en pantalla el listado total.
Afinando el mini mvc
Para afinar un poquito nuestro sistema nos convendria hacer que nuestros controladores y modelos no sean clases base, sino que extiendan de otras clases que contengan las funcionalidades básicas. De este modo todas las funcionalidades que agreguemos a nuestro ControladorBase y ModeloBase seran heredadas por los controladores y modelos que utilicemos.
libs/ControllerBase.php
1 2 3 4 5 6 7 8 9 10 11 | < ?php abstract class ControllerBase { protected $view; function __construct() { $this->view = new View(); } } ?> |
Como verán inclui en este controlador base la creación de la instancia de la vista en el constructor, es decir que ya no sera necesario hacer esto en los demas controladores. Deben recordar que si en los controladores sobreescriben el constructor, deben llamar al constructor de la clase base para poder tener la instancia de la vista (parent::__construct()).
Con esta clase base, nuestro controlador Items nos quedaria de la siguiente manera:
controllers/ItemsController.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | < ?php class ItemsController extends ControllerBase { public function listar() { //Incluye el modelo que corresponde require 'models/ItemsModel.php'; //Creamos una instancia de nuestro "modelo" $items = new ItemsModel(); //Le pedimos al modelo todos los items $listado = $items->listadoTotal(); //Pasamos a la vista toda la información que se desea representar $data['listado'] = $listado; //Finalmente presentamos nuestra plantilla $this->view->show("listar.php", $data); } public function agregar() { echo 'Aqui incluiremos nuestro formulario para insertar items'; } } ?> |
libs/ModelBase.php
1 2 3 4 5 6 7 8 9 10 11 | < ?php abstract class ModelBase { protected $db; public function __construct() { $this->db = SPDO::singleton(); } } ?> |
Similar a ControllerBase, nos permitira ahorrarnos el paso de iniciar PDO en cada modelo. Esta clase podria tener muchísimas funcionalidades mas y podria ahorrarnos escribir muchísimo código SQL si implementáramos en ella el patron Active Table por ejemplo, pero eso es otra historia.
libs/ItemsModel.php
1 2 3 4 5 6 7 8 9 10 11 12 13 | < ?php class ItemsModel extends ModelBase { public function listadoTotal() { //realizamos la consulta de todos los items $consulta = $this->db->prepare('SELECT * FROM items'); $consulta->execute(); //devolvemos la coleccion para que la vista la presente. return $consulta; } } ?> |
El último cambio está en el FrontController pero es mínimo, solo es la inclusión de los archivos que contienen las clases Base para que puedan ser heredadas.
Aclaraciones finales
1. Esta es una forma sencilla de implementar mvc con poo, no quiere decir que se ala única ni la mejor, hay algunas variantes pero me parecio bastante mas sencilla de comprender de esta manera.
2. Cuando me refiero a motor de plantillas y plantillas no lo tomen tan literal, fijense que las plantillas son simples .php donde igual se puede incluir codigo php de cualquier tipo. Solo es una manera sencilla y liviana, sin tener que usar Smarty u otro motor de plantillas.
3. Abierto a sugerencias :p
Links de interes
1. Building a simple MVC system with PHP5: Implementa una clase Router y otra Registry, aunque en ingles, esta bastante claro.
2. Todos los archivos del primer ejemplo.
3. Todos los archivos del segundo ejemplo.
4. Google
Otros artículos
130 comentarios en “Introducción a MVC con PHP, segunda parte”
Deja tu comentario
El blog funciona con Wordpress y Simpla theme

March 1, 2008 a las 5:48 pm
En mi opinion, esta implementación es util para dos cosas, proyectos pequeños y aprender el paradigma MVC y POO en el camino, igualmente es bueno tenerte de regreso, por ahí anda mootools 1.2b para que le tengas en cuenta ^^
March 1, 2008 a las 5:51 pm
imzyos, esta implementación no pretende mucho mas que eso :p Y ya le voy a echar una miradita a mootools, hace bastante que no uso nada nuevo.
Saludos, me alegro que sigas por aqui.
March 2, 2008 a las 4:20 am
síp, a eso me referia cuando decia que solo se podia usar para dos cosas, y el que te sigue es Google Reader ^^
March 6, 2008 a las 6:13 pm
Exelente explicacion tenia algunos meses esperando esta segunda para muy bueno espero sigas poniendo articulo ya que lo explicas muy … muchas gracias.
March 7, 2008 a las 9:15 am
Gracias por tu comentario Sergio
March 7, 2008 a las 12:50 pm
Bueno y si quisiera implementar este sistema MVC en sitio utilizando Smarty, este no seria uin buen punto de partida o tendria que tener mas cosas en cuenta.
Lo digo pues no me gusta armar sitios amarrados a un FRAMEWORK en especial.
Alguna sugerencia…. ?
March 7, 2008 a las 1:02 pm
A mi me parece un buen punto de partida solo si hablamos de un sistema chico, de hecho, el primer mvc que aplique tenia una estructura similar a ésta. Puedes mejorar esas url facilmente y el resto es lo de siempre, lo irás puliendo a medida que lo vayas probando.
Saludos
March 7, 2008 a las 1:10 pm
Federico.. en estos momentos estoy armando lo que seria el core de mi aplicación y estoy tomando loq eu posteastes en el articulo como punto de partida… con Ciertos cambios…
1. usando Smarty
2. Usando una clase Preemsamblada para el acceso ala base de datos “Postgres” y la generación de consultas Class: classpgDB
3. Usando Postgres en ves de Mysql.
4. usando Konstantes en ves de Variables y la clase COnfig.
De resto tu guia me aprecio genial estaba varios dias armando esto y no me daba de todas maneras estoy en proceso comento al terminar.
March 7, 2008 a las 1:14 pm
Bueno y si el sistema se convierte en un sistema grande… que puede pasar o que podria hacer para estar preparado o que me recomiendas….. pues todo comienza pequeño pero puede crecer y crecer…..
March 7, 2008 a las 2:26 pm
muy bueno, hacia rato que lo estaba esperando, estaría bueno que puedas mostrar como es el manejo de los formularios en estos ejemplos y como implementar url amigables en el mismo.
Te felicito aprendi mucho con tus articulos, y espero mas jejeje
March 11, 2008 a las 9:57 pm
@mecano, si crece en “contenido” debes prever que puedes llegar a usar muchos controladores con muchas “plantillas”, en ese caso creo que yo organizaría de otra manera la estructura de directorios.. ¿quiza una carpeta para cada controlador dentro de la carpeta de vistas? no hay mucho para tener en cuenta a nivel MVC.
@lucas, el manejo de formularios no varia mucho, supongamos que deseas insertar un elemento… en ese caso el action del formulario deberia ser algo como:
ejemplo-poo/?controlador=Items&accion=insertar
Y en la acción insertar del controlador Items colocas el código para procesar el formulario, donde puedes hacer uso de $_POST para recibir las variables.
Saludos, muchas gracias por sus comentarios… me animan a escribir :p
March 12, 2008 a las 2:28 pm
si es logico lo que dices manejar carpeta por controladores en las vistas agruparía la cantidad de php que se genera…………….una duda en el frontcontroller como se hace para redirigir internamente después de cierta accion………. por ejemplo después de un logueo y verificación contra la base de datos enviar a la pagina de usuarios registrados…=? GRACIAS De ANTEMANO
March 13, 2008 a las 6:24 am
Simplemente felicitarte por tu página es excelente.
Un saludo
March 13, 2008 a las 6:34 am
la ideal del modelo MVC esta bien, lo que no me gusta es que partir el codigo en 1000 partes es perdida de tiempo.
tengo 2 años desarrollando en ratos libres un framework propio pero este sin MVC, la ideologia es un autogenerador de todo lo tipico para disminuir el tiempo de desarrollo, expandible y que todo sea personalizable al 100%, para hacer lo mismo del ejemplo solo escribo
$conf["sql"]=”SELECT * FROM items”;
$conf["plantilla"]=”plantilla_demo”;
$valor=PlantillaGeneral_mash($conf);
y listo!!!!, el html de la plantilla se administra por medo de un panel y las variables por etiquetas; al mismo tiempo toda la aplicacion entra con multiples niveles de cache parciales y/o totales acelerando la aplicacion, ademas de generacion automatica de metas, etc.
por ejemplo el crear un formulario de altas bajas cambios se hace tambien con pocos comandos, va un ejemplo sencillo
// campos de captura
$form["sql"]=”select titulo,foto,fecha from informcion”;
// personalizando tipo de datos
$form["tipo"]["informacion___foto"]=”archivo”;
$form["tipo"]["informacion___fecha"]=”fecha”;
$form["default"]["informacion___fecha"]=”01/04/2008″;
//listado de elementos en la tabla
$conf["sql_listar"]=”select id, titulo from informacion”;
// referencias de trabajo de BD
$conf["sql_id"]=”id”;
$conf["default"]=”listar”;
$conf["tablas"]["actualizar"]["informacion"]=”id”;
$conf["tablas_eliminar"]=”informacion”;
$conf["idtablas_eliminar"]=”id”;
$valor=abc_mash($form,$conf);
toda la parte visual es personalizable mediante parametros extras, mientras tanto ya funciona con la vista por default
otras funciones integradas: validaciones varias de ellas automaticas por ejemplo para ataques XSS, multiples librerias de ajax mootols jquery prototipe etc, widgets de calendaros fck colorbox listbox checkbox etc, capacidad de insertar codigo PHP adicional por medio de parametros sin necesidad de modificar el codigo fuente, niveles de permisos ilimitados, alta velocidad de respuesta, ligero en procesador, multidioma, permite agregar cualquier libreria externa a cualquier lado y un millon de cosas extras
solo que ando indeciso de sera version comercial, libre o mixta
espero comentarios para tomar la desicion
March 13, 2008 a las 8:43 am
@mecano, internamente no lo he hecho…eso yo lo hago simplemente redireccionando con header(“Location: etc”); , logicamente puedes crear un método redirect($url) para hacerlo mas rápido. Igual supongo que no seria en el frontController, sino en el Controlador encargado del login…
@Jorge, muchisimas gracias por tu comentario
@mashter, el tema es que la base del MVC es la separación en capas je,… y ahi sus principales ventajas. Entiendo que lo encuentres una perdida de tiempo porque yo al principio senti lo mismo, pero con el pasar de los proyectos, correcciones, extensiones y demas… te puedo asegurar que valio la pena implementarlo cada vez que pude hacerlo.
Tu “Framework” me suena mas a CMS/Generador je y sinceramente no me tienta mucho. Claro está que no lo vi y me baso en otros sitemas de funcionalidades similares que vi y no me gustaron por la manera que tenian de hacerlo, teóricamente, expandible y personalizable.
Con respecto a la licencia, poco te puedo decir… yo personalmente no pagaria por un sistema de ese tipo, pero también ten en cuenta mis prejuicios jeje. Espero te sirva de ayuda mi comentario.
Saludos.
April 1, 2008 a las 8:15 pm
como seria el singleton para usar la conxion a mysql comun que se hace con php sin usar ningun liberia?
April 4, 2008 a las 8:11 pm
hola otra consulta:
como puedo hacer para que el error de no se encuentra el controlador salga en el template?
salu2
April 4, 2008 a las 8:18 pm
Hola lucas, podrias reemplazar la siguiente linea del FrontController:
die(‘El controlador no existe – 404 not found’);
Por algo como:
header(“Location: errores/404.php”);
Saludos
May 1, 2008 a las 1:13 pm
muy claro el articulo, y de mucha utilidad para comprender el mvc
gracias!
aprovecho para preguntar si les falta mucho para apagar los incendios, el humo que nos estan mandando ya no nos deja respirar
saludos uruguayos
May 1, 2008 a las 6:27 pm
Este articulo es excelente,llevaba varios días buscando algo con lo que iniciarme en el mvc y realmente no encontré nada tan bien redactado. Muchas gracias y sigue publicando artículos como este.
June 2, 2008 a las 11:36 am
Felicidades Fede!!
Me ha parecido muy interesante el articulo, y único, siendo la pastillita roja de muchos, ya que a nivel MVC, PHP y en Español hay 0,.
Espero que sigas publicando más articulos relacionados con este tema
.
Un saludo.
Sergio.
June 2, 2008 a las 11:53 pm
Te agradezco mucho el comentario y tu visita Norter
June 4, 2008 a las 10:10 pm
Hola
Felicidades por tu tutorial, es muy detallado, claro y simple, y tambien interesante ya que los patrones estan siendo utilizados en el desarrollo de aplicaciones.
Muchas Gracias.
June 13, 2008 a las 8:18 pm
Muy bueno el tutorial, hacia falta uno tan clarito, lo estoy usando en un sitio personal que comence a realizar sobre php…
Saludos y esperamos mas tutoriales
Graciasssss
June 14, 2008 a las 7:11 am
estoy comenzando con esto de mvc y entiendo bien el procedimiento en general, pero tengo 2 dudas sobre algunas sentencias.
1.- en el archivo controller.php esta lo siguiente:
//Le pedimos al modelo todos los items
$listado = $items->listadoTotal();
//Pasamos a la vista toda la información que se desea representar
$data['listado'] = $listado;
mi duda es:¿que hace esa palabra ‘listado’ dentro de los corchetes en el arreglo data?
2.- Luego se le envia el arreglo $data al archivo view.php
//Finalmente presentamos nuestra plantilla
$this->view->show(“listar.php”, $data);
y en view, $data es asignado a la variable $vars q es un arreglo tambien.
en el archivo view.php esta la siguiente sentencia:
//Si hay variables para asignar, las pasamos una a una.
if(is_array($vars))
{
foreach ($vars as $key => $value)
{
$$key = $value;
}
}
me podrian explicar que siginifca esa doble $$, no la conocia siempre he visto que las variables llevan un solo $.
Bueno esas son mis dudas, por lo demas encuentro muy bueno el articulo, haber si alguien me responde o me aclara un poco.
June 15, 2008 a las 12:23 am
Gracias por sus comentarios gente
Hola @palotex !
>mi duda es:¿que hace esa palabra ‘listado’ dentro de los corchetes en el arreglo data?
Estás en el controlador y le pasas las variables a la Vista por intermedio de un arreglo ($data), la palabra ‘listado’ es en este caso, la identificación (key) de la variable que estás pasando a la vista/plantilla.
>me podrian explicar que siginifca esa doble $$, no la conocia siempre he visto que las variables llevan un solo $.
Eso se llama “variable variables” y puedes ver para que sirve con ayuda de ejemplos en el manual.
En este caso puntual lo utilizamos para pasar las variables directamente a la plantilla. Fijate que tenemos todas las variables de la vista en un arreglo data, podriamos usar directamente este arreglo desde la plantilla haciendo algo como:
< ?php echo $data['listado']?>
Pero para hacerlo un poco mas sencillo, utilizamos $$ para convertir $data['listado'] en $listado y logramos poder usar la variable sin nombrar al arreglo que en un principio la contenía:
< ?php echo $listado?>
Espero que te sirva mi comentario.
Saludos
June 18, 2008 a las 4:11 pm
Me parecio un buen ejemplo
pero he tenido un problema y no logro entender por que pasa.
el problema es el siguiente:
escribi el codigo y al ejecutarlo me salieron errores,
todo estaba exactamente igual, escrito de la misma forma y me salia un error por la clase ModelBase el erro era de que el objeto no se puede crear o algo asi, alguien podria decirme porque pasa.
y por favor quisiera ver un ejemplo de como implementan lo de colocar un formulario.
quisiera ver el ejemplo de la funcion agregar
June 26, 2008 a las 12:15 am
Veronica, sin ver los errores es dificil ayudarte pero se me hace que lo mas seguro es que tu servidor no soporte PHP5 y este ejemplo es especificamente para PHP > 5
La funcion agregar y el uso con formularios no tiene muchas complicaciones. El action del form seria:
?controlador=Items&accion=agregar
Luego en el controlador tienes una accion agregar donde trabajas igual que siempre:
function agregar()
{
if($_POST)
{
$nombre = $_POST['nombre']
/* aqui el resto */
}
}
Saludos!
June 26, 2008 a las 4:28 pm
gracias por la respuesta.
pero tengo otra duda
hice la funcion agregar como me indicas, el action
para mi ejemplo es “index?controlador=items&accion=agregar”
primero inclui la vista agregar.php
luego el modelo donde hice una funcion para insertar item q es asi mas o menos insertar($id_item,$item),
pero no me inserta nada no hace nada, solo me manda otra vez al formulario.
gracias espero q me puedan ayudar……
a ver si colocan un ejemplo mas completo.
June 26, 2008 a las 6:01 pm
Hola Vero, sin ver errores ni codigo la verdad no te puedo ayudar mucho.
En principio asegurate de que tengas configurado php para mostrar los errores, revisa error_reporting en el manual de php.
Luego podrias usar “echo” en las distintas partes de tu script para ver que es lo que se “ejecuta”, que no, si hay error con la bd, etc.
Saludos
July 9, 2008 a las 8:08 am
Un saludo!
Antes que nada, excelentes artículos y muy útiles.
Quizás sea una pregunta muy tonta y un pelín offTopic, pero ahí va:
me he fijado en que para aquellas partes del programa que vas a incluir en muchos sitios (como el config, o la instancia de view, etc) implementas un singleton, que no hace más que comprobar si ya hay alguna instancia del objeto en cuestión. ¿Sería esto similar a realizar un require_once() en el caso de que no anduviéramos con objetos?
Un saludo y enhorabuena.
July 9, 2008 a las 1:29 pm
Hola federico
Muy bueno el tutorial, y mucho mejor con el ejemplo. Me esta ayudando en gran manera.
Saludos
July 10, 2008 a las 8:41 pm
@Javier, si, en cierto modo si. En el caso de los objetos y singleton mantienes una única instancia de la clase… y por consiguiente puedes acceder a las propiedades/atributos del objeto desde cualquier parte donde hagas la llamada al singleton.
July 11, 2008 a las 5:54 pm
Buenas,
Muy bueno el post. Aun así despues de provarlo me ha surgido una duda relacionada con el ultimo mensaje. Estamos de acuerdo con el utilizar una unica instancia de los objetos. La duda es, cual es el ambito de las instancias, es decir cuando dejan de existir los objetos instanciados?
July 11, 2008 a las 9:34 pm
Hola Victor, los objetos existen mientras exista al menos una referencia a ellos. Juega un poco con el método __destruct de PHP5 y te darás cuenta rápidamente como funciona.
Un saludo
July 14, 2008 a las 5:34 am
public static function singleton()
{
if (!isset(self::$instance)) {
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
}
¿que significa _CLASS_ en ese codigo?
July 14, 2008 a las 2:57 pm
Hola, __CLASS__ es una constante que indica el nombre de la clase actual, mas info y ejemplos.
Saludos
July 14, 2008 a las 4:24 pm
Una pregunta me gusatria saber si realizaras una parte 3 de este exelente tutorial .. saludos que estes bien y espero luego saques otro tutorial sobre mvc o tus otros temas por que estan muy bien explicados
August 11, 2008 a las 12:27 pm
Una consulta, implementando este patron MVC, me tira un error cuando instancio una clase que herede de otra clase que esa a su vez hereda de ModelBase.
Uncaught exception ‘PDOException’ with message ‘SQLSTATE[42000] [1049] Unknown database ‘pruebas” in C:\wamp\www\Turnero\libs\SPDO.php:9 Stack trace: #0 C:\wamp\www\Turnero\libs\SPDO.php(9): PDO->__construct(‘mysql:host=loca…’, ‘root’, ”) #1 C:\wamp\www\Turnero\libs\SPDO.php(16): SPDO->__construct() #2 C:\wamp\www\Turnero\libs\ModelBase.php(16): SPDO::singleton() #3 C:\wamp\www\Turnero\models\RetiroDeNumeroModel.php(10): ModelBase->__construct() #4 C:\wamp\www\Turnero\controllers\RetiroDeNumeroController.php(12): RetiroDeNumeroModel->__construct() #5 C:\wamp\www\Turnero\libs\FrontController.php(47): RetiroDeNumeroController->index() #6 C:\wamp\www\Turnero\index.php(3): FrontController::main() #7 {main} thrown in C:\wamp\www\Turnero\libs\SPDO.php on line 9
alguien sabe que es ?? o como solucionarlo?? saludos!! expectacular tutorial
August 12, 2008 a las 10:44 am
@Sergio Armando, la verdad no tengo en mente una 3er parte. ¡¡Si espero poder escribir algo nuevo pronto!! faltan un poco de ganas pero ya llegaran.
@Adrian, dice Unknown database ‘pruebas’
Los datos de conexion son correctos? existe la base de datos?
August 26, 2008 a las 4:27 pm
Excelentes ambos posts Federico.
Una consulta: vas a incluir algo de seguridad en los siguientes posts?
Me interesaría agregar un control de acceso a una aplicación creada con este framework, pero no se me ocurre de momento cómo hacerlo
Saludos.
September 8, 2008 a las 2:33 pm
Antes que nada, muchas gracias Federico, esta excelente el articulo, adopte este framework para comenzar a trabajar con POO y MVC, ya integre smarty, solo que me quede un poco confundido con el manejo de las sesiones, pues todo va sobre la marcha y sigo aprendiendo, me gustaria saber cual es la manera mas optima de manejar las sesiones o en que nivel las debo de manejar, o si podrias pasarme algun link para investigar.
Saludos
September 9, 2008 a las 6:58 am
Buenas,
Una duda sobre un problemilla, he realizado un modulo para gestionar los destacados de una web con la base que explicas en el tutorial i localmente todo funcionava correctamente.
El problema ha surgido cuando he puesto en produccion el modulo.
En una de las acciones que invoca 2 metodos del modelo se me corta la ejecucion. Te adjunto la acción aver si ves alguna cosa sospechosa i mes puedes echar una mano.
public function carregarFormSeccions()
{
require ‘models/DestacatsModel.php’;
//Creamos una instancia de nuestro “modelo”
$destacat = new DestacatsModel();
//Le pedimos al modelo todos los items
$pre_seccions = $destacat->ObtenirSeccions();
// por cada seccion consultamos el numero de destacados
foreach($pre_seccions as $item)
{
$quants = $destacat->QuantsDestacats($item['id']);
// si el numero de destacados es menor a 5 lo añadimos a $seccions
$quants = $quants->fetch();
if ($quants['cont'] view->show(“destacats_esc_seccio_view.php”,$data);
}
Gracias.
September 9, 2008 a las 7:04 am
Hey,
No se por que motivo no me deja colgar el codigo de la accion completo. Se come un trozo i no se porque no lo intento mas.
Si tienes alguna sugerencia ya diràs.
Gracias
September 9, 2008 a las 11:48 am
@Martin, realmente no tengo pensado volver a tocar este tema a corto plazo, primero quiero volver a escribir!. De todos modos hecha un vistazo al proyecto surforce. Es un CMS hecho con ZendFramework y su implementacion de MVC. Puedes sacar muchas ideas y tomarlo como base aunque no utilices dicho Framework.
@Raul, las sesiones las puedes manejar a nivel controlador, quiza con alguna clase que te ayude a manejarlas. Mismo consejo, hecha un vistazo al surforce cms.
Muchas gracias a los dos y me alegro que les haya servido el articulo mas no sea como un punto de partida
@Victor, al parecer los filtros de wordpress cortan tu codigo. Tenes habilitado los errores? es raro que se quede en blaco :/. Prueba ir comentando porciones hasta que puedas detectar cual es el fallo.
Saludos.
September 9, 2008 a las 2:23 pm
Buenas,
Recapitulando:
El motivo de mi mensaje era intentar solucionar un problema con una accion utilizando la base de MVC que tu propones en el post.
Depurando poquito a poquito me he dado cuenta de que el error se da cuando invoco mas de un metodo del Modelo(M) i unicamente si estos metodos del Modelo ejecutan el metodo db->execute(). Si me cargo la parte de tu codigo que hace que apliques el patron Singleton, es decir, el metode Singleton de la classe SPDO (eliminando el if ) funciona correctamente.
Lo mas estraño es que en mi ordenador personal funciona correctament, por no decir de fabula. Jo diria que es por algun motivo de configuracion, aunque si tienes alguna sugerencia….
En fin, una vez superado de alguna manera el problema que ha echo que vuelva corriendo a visitar tu post, me gustaria comentarte unas cosillas, a ver como las ves tu ja que todo lo que hago ultimamente sin cms lo hago partiendo de tu base.
Alla va:
-Como se puede solucionar el tema de que las vistas sean accesibles?
-Cuando haces el request de los parametros solo lo haces por get. Si se quisiera hacer el request por post, ¿lo pongo a continuacion del get?
-La validacion de usuarios donde la sueles poner en cada accion o en el FrontControler?
-Como se puede solucionar el echo de que cada modelo requiera un controlador?
En fin, gracias nuevamente por habrir-me las puertas al MVC con php.
Saludos.
September 9, 2008 a las 2:44 pm
@Victor
Con respecto al error tendria que revisarlo pero me resulta raro porque utilizo actualmente esto en algunos pequeños trabajos y no tengo problemas. Lo mirare cuando tenga un momento.
Con respecto a las preguntas:
-Como se puede solucionar el tema de que las vistas sean accesibles?
No entiendo, podrias explicar un poco mejor a que te refieres?
-Cuando haces el request de los parametros solo lo haces por get. Si se quisiera hacer el request por post, ¿lo pongo a continuacion del get?
El metodo POST funciona de la misma manera que siempre. Por ejemplo en el action del form colocas
?controlador=Items&accion=agregar
En el controlador Items, en la accion agregar recibes las variables con el arreglo $_POST, nada mas.
-La validacion de usuarios donde la sueles poner en cada accion o en el FrontControler?
La validacion de usuarios en los controladores (en su constructor), puedes crear un controlador mas aparte del base que ya contenga la validacion y hacer que los controladores que necesiten validacion hereden de este.
-Como se puede solucionar el echo de que cada modelo requiera un controlador?
En el controlador puedes usar varios “modelos”, no hace falta que crees un controlador para cada uno.
Me encantaria poder complementar este articulo con un ejemplo un poco mas real, intentare hacerme un lugar y de ganas jeje. Mientras tanto te comento lo que a los otros chicos, mira el proyecto surforce cms; esta hecho con ZendFramework, pero mirando como utilizan cada componente puedes darte una idea de como se pueden hacer las cosas o resolver alguna duda en particular (como la de la validacion de usuarios).
Un saludo
September 19, 2008 a las 7:36 am
Hola!estoy trabajando con MVC pero sin objetos, en mi vista tengo una serie de checkbox. Lo que quiero es enviar al controlador el listado o arreglo nose, con los values de los checkbox que se hayan seleccionado (checked) como hago????Agradeceria mucho tu pronta respuesta =o)
September 19, 2008 a las 3:25 pm
Introducción a MVC con PHP…
MVC (Modelo Vista Controlador) es un patrón que consiste en separar el diseño de nuestra aplicación en tres capas, la lógica de datos (Modelo), la interfaz de usuario (Vista), y el Controlador quien invoca cambios al modelo y los presenta en la vis…
September 21, 2008 a las 7:52 pm
Hola:
hice un sitio bansandome en este tutorial, en mi localhost anda perfecto pero cuando lo subo al servidor solamente anda el controlador de inicio y despues me sale el error 404, un amigo me comento que puede ser que yo uso el nombre de archivo asi LoginModel.php pero no estoy seguro ya que probe pasando todos los archivos a minusculas y nada, alguna idea?
salu2
September 22, 2008 a las 12:03 am
Lucas, que raro.. lo estas usando tal cual o agregaste URL amigables? si estás usando URL amigables puede ser que tu hosting no soporte el mod_rewrite o lo que hayas usado. Caso contrario, un 404 solo pasando variables por GET, no lo entiendo, habría que revisarlo.
Saludos
September 22, 2008 a las 5:03 pm
Federico,
Esta exelente tu articulo, la verdad que hace rato estaba buscando algo similar.
Me gustaria desarrollar una aplicacion aplicando este concepto, segui este tutorial y a la hora de probar me sale esto.
Fatal error: Class ‘PDO’ not found in C:\Archivos de programa\Apache Software Foundation\Apache2.2\htdocs\MVC3\libs\SPDO.php on line 2
September 29, 2008 a las 11:21 pm
federico:
aca esta el link de prueba http://www.onirico.tgame.es/
lo si haces click en el foto (que no se ve) deberia mostrarte unas noticias, pero no muestra nada :s
si me podes ayudar ya que se me esta atrasando un monton la entrega del proyecto.
salu2
September 30, 2008 a las 3:46 pm
@Luis supongo que no tienes instalado PDO, revisale con un phpinfo();
@Lucas, no entiendo. Cuando hago click ahi muestra algo, una tabla rota. Revisa la clase FrontController para ver que archivo carga. Viendo ese link mucho mas no te puedo ayudar.
Saludos
October 4, 2008 a las 12:42 pm
Era eso Federico, muchas gracias, otra consulta, tendrias un ejemplo sobre el manejo de clase Router y una de login implementando este estema?
October 15, 2008 a las 8:04 am
Hola Federico, veo que heres un crack.
Ha mi mesguatria aprender este tema del MVC ya he probado de pasar cose que tengo echas ha este sistema y no logro conseguirlo, heber si me podrias ayudar un poco. Mira estoy intentando pasar esto* a mvc y creo que esto tindreia que ir a modelo y los echo’s a vista pasando los datos atraves de control pero no consigo imaginar como. si he consegui pasar bases de datos simples sin filtrar ni dada pero nose como hacerlo que estan filtradas con barias bases mescladas.
Nos se si me he esplicado bien, (espero que si)
Ya me diaras que opinas
Saludos y muchas gracias
October 15, 2008 a las 8:12 am
No me daja poner el codigo de ejemplo??
October 15, 2008 a las 1:02 pm
He conseguido hacerlo pero no se si esta bien echo os dejo un zip para que os lo mireis si esta bien o se pude mejorar, o aportar algo mas. Seri bueno iniciarnos al Zend ya que te biene muchas cosas echas.
http://cenics.net/Archive.zip
October 20, 2008 a las 1:41 am
Federico,
Muchas gracias por ambos artículos (1ra y 2da parte), muy explicativos por lo demás, y útiles… tienes una forma coloquial de explicar las cosas que hace mucho más sencillo comprender.
Gracias nuevamente!!.
Saludos,
Juan Pablo
October 25, 2008 a las 4:45 pm
Hola, Federico.
En primer lugar, permiteme felcitarte por estos dos excelentes artículos introductorios a la arquitectura MVC.
Ya había metido un poco la cabeza en esto investigando sobre CakePHP y Symfony. Finalmente he rechazado el uso de frameworks, ya que prefiero que mi experiencia en programación web se forje en las bases.Por otra parte, sigo muy interesado en MVC.
A este respecto, una pequeña duda. Si la idea del Modelo es crear una capa de abstracción de los datos,¿por qué utilizar un patrón singleton en la BBDD? ¿no te limita esto a trabajar con una sola base de datos dentro de una misma aplicación? En todo caso ¿no se podría controlar que nunca se instancíe un objeto PDO con los mismos parámetros?
Que conste que entiendo que tu artículos sólo pretenden ser introductorios, sin pretender nunca criticar el trabajo aquí expuesto. Gracias.
November 3, 2008 a las 2:24 am
hola federico
bueno primero q nada felicitarte por el tutorial
pero me surge una duda, con el tema de los formularios y esto del MVC.
como es el modo de operacion del formulario? por ejemplo el login si tengo un controlador de loginController, que tiene un metodo login, como llamo este metodo desde la vista?
saludso
gracias !
December 14, 2008 a las 1:04 am
Excelente!
Felicitaciones , excelente tutorial y muy buena pedagogia. muchos escriben y no dicen o comunican nada. Muy bien!
creo q para acciones en formularios se debe de usar campos ocultos y tokens de session.
Saludos a todos desde Perú.
January 7, 2009 a las 5:14 am
[...] con el que trabajar en BmTotal. No hay mucho que explicar, ya que para hacerlo he estado siguiendo este tutorial, que está muy bien para ir empezando. He de decir que cambié la parte de las plantillas, pues ya [...]
February 3, 2009 a las 6:49 pm
Saludos. Muy buen tutorial, es justamente lo que estaba buscando para poder entender y crear mi propio MVC. Sin emabargo me queda una pequeña duda sobre el codigo en el View.php que recorre las variables:
if(is_array($vars)){
foreach ($vars as $key => $value){
$$key = $value;
}
}
Este recorrido para que funciona si en el listar.php llama directamente a la variable $listado de la clase ItemsController?
February 3, 2009 a las 9:34 pm
Continuando con mi duda anterior como se tranfiere los valores de los $key a while($item = $listados->fetch()) que esta en la vista? Y que significa el doble $$.
February 12, 2009 a las 2:13 pm
De verdad felicitaciones por este tutorial, esta explicado a la perfección y el material que muestra es mas que interesante.
Muy bueno de verdad! Sigue así
March 24, 2009 a las 12:36 am
Coye antes que nada felicitaciones por tu explicacion que para mi ha sido la mas clara y completa que he leido por internet. Ahora tengo unas dudas, en los ejemplos que he leido usualmente explican solo el paso de datos del modelo a la vista a traves del controlador, ahora como debo hacerlo si quiero realizar este proceso a la inversa, es decir, si quiero pasar datos de la vista al modelo a traves del controlador??? la cuestion esta en que quiero implementar formularios en algunas de mis vistas, que si para el ingreso de info, usuarios y autentificacion. Yo estoy iniciandome con el uso de este patron para un sistema que tengo que realizar, entonces al momento de enviar la info. de los formularios, a pesar de que en el action coloco el controlador respectivo no lo hace y no tengo ni idea de por q??? ademas como indico la accion que debe tomar si solo puedo especificar el el form es el controlador???. Muchas gracias de antemano y espero tu respuesta.
March 24, 2009 a las 1:43 am
Gracias por sus comentarios, disculpen no tener el tiempo para responder todos.
Cefranlly, siguiendo la logica de mis ejemplos, en el action del form podrias indicar lo siguiente:
?controlador=Items&accion=agregar
Controlador: Items.
Accion: agregar.
Una vez en el controlador, recibes la informacion de la vista con los arreglos $_GET o $_POST segun el method de tu form, y de ahi al modelo.
Espero haber aclarado tu duda.
Saludos
March 30, 2009 a las 2:31 pm
Buenos dias, antes que nada muchas gracias por tomarte la molestia para responderme. Ahora me ha surgido un problema, cuando intento enviar un formulario utilizo como tu me sugeriste, en el action=”index.php?controlador=usuarios&accion=validar” y tambien lo he hecho con action=”?controlador=usuarios&accion=validar” (este ejemplo para el login), y lo que hace es volver a cargar la pagina del login y no realiza ninguna accion, por que puede ser esto???
April 16, 2009 a las 9:16 am
Antes que nada, quiero agradecerte por tomarte la molestia de responderme. Ademas quiero decirte q es un muy buen ejemplo sobre MVC.
Pero tengo algunas apreciaciones a la hora de implementar tu ejemplo, al declarar:
class SPDO extends PDO
No encuentro hasta ahora PDO en ninguno de los archivos, sea del primero o segundo ejemplo.
De q clase se trata?
Por favor podrias ser mas especifico en esa parte, ya que hasta ahora no logro ejecutar la accion “listar” de ItemsController.
Muchas gracias.
April 16, 2009 a las 11:18 am
Hola Jose Antonio, PDO es una librería escrita en C que se instala directamente en el servidor (casi todos los hosting con php > 5 ya la traen), no está en ningun fichero .php. Escribi un articulo sobre ello aqui.
Para saber si la tenés habilitada tenes que hacer un phpinfo(); y buscar PDO, debe aparecer algo así:
PDO drivers mysql, sqlite2
pdo_mysql
@Cefranlly, habria que revisarlo.. asi mucho no te puedo decir. Lo siento.
Saludos
May 3, 2009 a las 10:20 am
Otra pregunta que queria hacerte como hago la comprobación de usuario. Yo habia pensado realizar un controlador Log que verifique el usuario y luego redireccione al home en caso de ser validado, ahora la cuestión seria como verifico si el usuario esta validado en cada controlador???
May 3, 2009 a las 10:09 pm
[...] Acá les dejo una guía publicada en Jourmoly donde nos explican como crear una aplicacion simple utilizando Modelo Vista Controlador, La guía esta distribuida en dos partes Parte 1 y Parte 2. [...]
May 5, 2009 a las 12:10 pm
Gracias por tus respuestas Federico, ahora aqui va otra duda que me ha surgido, por que cuando llamo a algún metodo de algún modelo no me deja realizar mas de un execute();???, es decir, si quiero incluir una misma información en dos partes, por que no me deja hacer el:
prerare(‘INSERT INTO “loquesea” VALUES(“:loquesea”)’);
binParam(“:loquesea”,$loquesea);
execute();
luego intento inserta la misma info en otra tabla
prerare(‘INSERT INTO “otratabla” VALUES(“:loquesea”)’);
binParam(“:loquesea”,$loquesea);
execute();
no me deja me muestra un error
May 5, 2009 a las 12:11 pm
ahhh todo esto en el mismo metodo de un modelo
May 20, 2009 a las 8:15 pm
Desde que leí tu artículo sobre MVC he estado programando bajo tu esquema y de verdad que los resultados son excelentes.
Ahora quiero agregarle ajax con la librería Jquery pero me gustaría que me orientaras como puedo usar dicha librería sin perder las ventajas de la estructura del MCV.
Igual con el javascript, es decir, como manejar validaciones en javascript sin dañar las ventajas del mvc.
Muchas gracias de antemano.
Saludos
June 4, 2009 a las 3:23 am
Muy buenos tus dos artículos, basándome en tú código estoy comenzando a hacer un miniMVC para uso personal en principio y luego quien sabe
Me gustaría seguir leyéndote…
Un saludo
Isidro
June 4, 2009 a las 7:13 pm
Hola federico, podrías ayudarnos a modelar la implemetación del patrón Observador para que las Vista logre comunciarse con el Modelo ya que en algunos casos es obligatorio dicha comunicación.
Gracias
June 18, 2009 a las 3:21 pm
disculpen por mi pregunta pero el patron mvc el modelo es muy aparte supuestamente tengo que llamar a mi objeto para asi darle por que de lo contrario voy a estar llamando funcion para cualquier cosa de mi modelo
asi que bueno creo yo!! pero si hubiera otra cosa me lo dicen.
que hago solo el modelo e paso el parametro ($consulta)
para no estar llamando a cada funcion y me evito todo ese problen de estar llamando a una funcion para cada cosa
July 7, 2009 a las 11:45 pm
El problema de Victor (estoy casi seguro).. . se debe a la versión de myslq que tiene instalada. En tu compu personal de seguro tienes la versión 5.0 y no te funciona con la versión 4.1.22.
Por otra parte el código está muy bien hecho … tarde varios días en descubrir ese pequeños detalle. Solucionalo actulizandote a la 5.0 o superior.
Saludos
July 8, 2009 a las 7:28 pm
ESTA MUY ENTENDIBLE Y DIDACTICO
July 19, 2009 a las 5:48 pm
[...] [...]
July 31, 2009 a las 1:46 pm
man estube leyendo el foro que pedistes ayuda estoy en plan h….. jeje
te recomiendo que coipes y pegues tu proyecto de aqui y cuando quieras hacer privilegios de usuarios crea una tabla con los menus que vas a crear segun los privilegios que tenga el usuario se le asigna desde una sesion ya dada y si quieres evitar el header puedes tambien una opcion con javascript pero no se recomienda es solo solucion ok
July 31, 2009 a las 1:50 pm
gracias por el code implemente el jqgrid a este code y el lado del modelo solo puse una variable como si fuera la consulta para no poner todas la funciones y en mi controlador esta mi consulta gracias
August 11, 2009 a las 2:29 pm
Saludos, excelente tutorial y muy claro por cierto de mucha utilidad, las gracias respectivas por este aporte.
Quisiera q me ayudaras porfavor, estas son las interrogantes:
1)¿como hago para utilizar una sola platilla HTML (1 sola vista) para todo mi sitio?, es decir, no repetir todo el codigo html en las vistas de mi web solo lo necesario, algo como lo q hace joomla por ejemplo, porfavor basate en el ejemplo q has mostrado, ya q he intentado utilizar una sola plantilla y pierdo algunas referencias por ejemplo la variable: $listado, en la vista listar.php me lanza un error y dice q no es un objeto, cuando quiere hacerle un fetch() en un while para mostrar los items.
Esq mi intencion es llamar a cada area de mi web con un simple:
esto desde mi plantilla principal:
$this->display_header();
$this->display_content();
$this->display_bottom(); etc…
2) Quisiera q me explicaras cual es la intension de utilizar este codigo en el archivo View.php:
if(is_array($vars))
{
foreach ($vars as $key => $value){
$$key = $value;
}
}
Te agredesco las respuestas y la ayuda de antemano, gracias.
September 11, 2009 a las 10:05 pm
Independientemente de que lo considero muy util e instructivo, lo mas importante es tu intención, muy pocos hoy en dia publican para otros materiales donde se puedan comprender las enrredadas teorias sobre estos conceptos, a muchos les toma incluso años comprender dando tumbos entre distintos autores y tendencias…., creo que todos debemos seguir tu ejemplo estimado Federico.
September 15, 2009 a las 10:49 pm
A partir de la version 5 de php existe la funcion __autoload para que haga los includes automaticamente cuando se instancia una clase. En este tipo de ocaciones me parece realmente interesante.
Muchas gracias por el tutorial, de verdad que es genial
September 25, 2009 a las 5:27 am
Me sale este error:
Warning: PDO::__construct() [pdo.--construct]: [2002] Argumento inválido (trying to connect via unix://) in /opt/lampp/htdocs/cachito/libs/SPDO.php on line 9
Vi en los cometarios q a alguien le paso algo similar..
creo que los datos de conexion son correctos.. bueno muchas gracias!!! muy explicativo
September 25, 2009 a las 6:43 pm
ya encontre el problema o al menos como solucionarlo.
Bueno lo que tuve que hacer fue cambiar en alrchivo config.php el nombre del host, en vez de localhost puse 127.0.0.1
O sea:
cambie:
$config->set(‘dbhost’, ‘localhost’);
por:
$config->set(‘dbhost’, ’127.0.0.1′);
si alguien sabe por que de la otra forma no me anda se los agradeceria mucho
November 9, 2009 a las 9:34 am
Muy bueno el tutorial!
Justo andaba buscando poder hacer algo parecido pero sin saber siquiera que nada sobre el patrón MVC, simplemente intentando copiar el sistema de mi empresa desarrollado en java y “migrarlo” a PHP.
De todas formas se me plantean un par de dudas.
Cómo hacer para poder insertar más de un displayer (acción/plantilla) en una página? P.ej. Una acción para el menú, otra para pintar una acción de recuperación de un item en concreto, … etc.?
De todas formas, es un buen punto de partida para empezar a investigar
Un saludo y muchas gracias!
December 6, 2009 a las 10:46 pm
Hola, te hago una consulta estoy tratando de separar un poco mas el tutorial que hiciste, la idea es poder tener el backend en una carpeta admin y el frontend en una carpeta website.
el problema que tengo es que no me reconoce el controlador mi estructura es asi:
admin
controladores
nombrecontrolador
nombrecontrolador.php
template
nombretemplate.html
y en el frontController armo asi todo:
//Formamos el nombre del Controlador o en su defecto, tomamos que es el IndexController
if(! empty($_REQUEST['controlador'])){
$controllerName = $_REQUEST['controlador'].’Controller’;
$controllerFolder = $_REQUEST['controlador'];
}
else{
$controllerName = “indexController”;
$controllerFolder = ‘index’;
}
//Lo mismo sucede con las acciones, si no hay accion, tomamos index como accion
if(! empty($_REQUEST['accion']))
$actionName = $_REQUEST['accion'];
else
$actionName = “index”;
//verifico si esta en el admin o no
if(!isset($_SESSION['admin'])){
$controllerPath = $config->get(‘controllersFolder’) . $contrllerFolder . ‘/’.$controllerName.’.php’;
$config->set(‘viewsFolder’,$config->get(‘controllersFolder’) . $controllerFolder . ‘/templates/’);
$templates=$config->get(‘adminControllerFolder’) . $controllerFolder . ‘/templates/’;
$config->set(‘viewsFolders’,$templates);
//$error404 = $config->get(‘controllersFolder’).’error404/error404Controller.php’;
}
else{
$controllerPath = $config->get(‘adminControllerFolder’) . $controllerFolder . ‘/’.$controllerName.’.php’;
$templates=$config->get(‘adminControllerFolder’) . $controllerFolder . ‘/templates/’;
$config->set(‘viewsFolders’,$templates);
$config->set(‘templates’,$config->get(‘adminViewsFolder’));
$error404 = $config->get(‘adminControllerFolder’).’error404/error404Controller.php’;
}
//Incluimos el fichero que contiene nuestra clase controladora solicitada
if(is_file($controllerPath))
require $controllerPath;
else
die(‘El controlador no existe – 404 not found’.$controllerPath);
//require $error404;
//echo $error404;
//Si no existe la clase que buscamos y su acción, tiramos un error 404
if (is_callable(array($controllerName, $actionName)) == false)
{
trigger_error ($controllerName . ‘->’ . $actionName . ‘` no existe’, E_USER_NOTICE);
return false;
}
//Si todo esta bien, creamos una instancia del controlador y llamamos a la accion
$controller = new $controllerName();
$controller->$actionName();
pero siempre me tira el die(‘El controlador no existe ..)
cuando imprimo el controllerPath me marca bien la ruta:
admin/controladores/index/indexController.php
en que le estoy errando.
Desde ya muchas gracias
December 19, 2009 a las 6:45 pm
Hola!
Federico, el tutorial está muy bueno y sencillo, realmente te felicito. Lo que sí, de acuerdo a lo que vi muy rápidamente de tus fuentes, me atrevería a recomendar un par de cositas complementares, a ver:
- mejorar la definición de los atributos y explicitar la visibilidad, a pesar del lo debilmente tipeado que es PHP …
- tratar los errores con Exceptions personalizadas en lugar de funciones disparadoras(trigger_error), para mantener todo lo más OO posible…
Después, está muy bueno lo de PDO para extender a SGDBs distintos, pero yo particularmente trato de trabajar con un SGDB específico; tomemos como ejemplo MySQL! Hago todo con la clase MySQLi, y sin trabajar con statements… porque tratar errores me parece más delicado en algo “universal”, pues depende de como cada SGDB los manipula y de los métodos / funciones que el lenguaje ofrece para cada motor…
En mi caso de MySQL, tengo una clase ErrorConexionException($codigoError) que trata los errores de conexion (schema no especificado, acceso denegado, etc.) de acuerdo al codigo de error que el SGDB devuelve al método mysqli::errno, y otra clase ErrorQueryException($codigoError, $queryEjecutada) que trata los errores de ejecución (error de sintaxis, etc.) de query de acuerdo al codigo de error que el SGDB devuelve al método mysqli::errno y la query ejecutada (un atributo de la clase, obviamente)… Además, con las propiedades nativas de la clase Exception, puedo MUY fácilmente averiguar el archivo, la linea de codigo fuente y hacer traza de las excepciones, lo que aprovecha mejor la OO y facilita el mantenimiento y los UnitTests…
Bueno, esto es todo!
Felicitaciones y espero que los comentarios te resulten productivos.
Saludos!
January 2, 2010 a las 7:12 pm
Hola estimado, me encanto su articulo la cual estoy poniendo en practica, pero me salta una duda ¿como puedo modularizar una pagina con esta metodologia? ya que si hago un link me manda a una pagina nueva y no modulariza la pagina en este caso todo en el index.php
espero tu respueta
saluda atte.
January 25, 2010 a las 5:11 pm
En la linea 38 del archivo “libs/FrontController.php” Se genera un “Warning” que dice algo asi como: “cannot be called statically”. Como puede ser evitado dicho aviso??
February 9, 2010 a las 1:19 pm
Excelente el articulo, muy facil de entender y bastante practico, pero quiesiera ver o que me facilites algun articulo o ejemplo que contenga la utilizacion del patron que nombras (Active Table).
Quedo atento a tu respuesta, y de nuevo felicitaciones.
March 2, 2010 a las 10:21 am
Interesante articulo, como dice Alejandro fácil de entender y práctico.
Felicitarte por el trabajo y estaré atento al tema de Active Table
March 8, 2010 a las 2:53 pm
Ami tambien me gusto el tutorial, solo que ODIO PDO, teniendo toda una gama de clases muy manipulables.
March 19, 2010 a las 11:11 am
Hola estoy empezando con esto de MVC y muy buena los dos artículos que publicaste, excelentes de verdad, saludos desde Venezuela..
March 24, 2010 a las 5:33 pm
Hola un apregunta como has manejado las excepciones por ejemplo cuando Try y catch deberia estar en $consulta = $this->db->prepare(consulta sql);
$consulta->execute() por si algun erro en el digitado de la consulta hubiese por ejemplo?? Podrias colocar un ejemplo.
March 25, 2010 a las 4:57 pm
Hola, una consulta como se podria implementar ajax (con jquery) en este tutorial?
salu2
May 12, 2010 a las 12:20 am
me hace falta saber como programo el insertar en el MVC,
ya tengo la consulta en el modelo y todo el codigo llega bien hasta el modelo pero no me inserta
necesito su ayuda urgente k tengo tesis el lunes
gracias de antemano
May 22, 2010 a las 7:28 am
Muy buen tutorial. Es el que mejor me ha ayudado a entender de verdad los entresijos del patrón MVC. De todas formas hay una cosa que no me queda clara del todo.
Por lo que he visto, generalmente cuando se usa este patrón de arquitectura, se utiliza al menos una vista para cada tipo de acción. En este caso veo que se utiliza una única vista View que lo que hace es cargar directamente la plantilla adecuada para la acción requerida, o sea, que en el directorio de vistas solo tenemos plantillas php, no clases de vistas. ¿No sería más cercano a una implementación MVC hacer una vista para cada acción y que esta sea la que cargue una de sus plantillas? Algo como lo que se hace en Joomla por ejemplo.
Un cordial saludo!
May 26, 2010 a las 3:02 pm
hola, buenas tardes.. excelente tutorial, felicitaciones!!!
te hago una pregunta?? como implementás AJAX con este modelo??
Muchas gracias
May 31, 2010 a las 9:55 pm
Gracias, muy bien explicado !
July 6, 2010 a las 3:21 pm
Hola desde Venezuela, excelente implementacion del patron MVC y otros conceptos, busque esto en google pq necesito hacer una aplicacion sencilla en php y decidi utilizar mvc, yo uso Symfony, pero sinceramente no sabia trabajar MVC con php solamente, me gusto tu ejemplo pq de forma clara haces cosas que uno ve en aplicaciones profecionales como por ejemplo Joomla 1.5.
Saludos desde venezuela y te animo de verdad a seguir escribiendo sobre estas cosas pq nos ayudan bastante sobretodo a esta parte del mundo, que te puedo decir sintiendo verguenza que apenas se esta conociendo PHP, no asi el PATRON MVC y mucho menos el uso de Framework en PHP, lo ultimo no tiene nada que ver, pero si que hacen un uso eficiente de MVC los framework con Symfony.
July 19, 2010 a las 5:22 am
Buenísimas publicación.
Pero solo un detalle vemos que realizamos desde la clase ItemsModel una function de una consulta y despues mostramos los resultados en el template html.
Pero si quisieramos liberizar la tabla de la consulta,, crearíamos una function nueva en la clase del modelo???????????????
Muchsimas gracias
September 10, 2010 a las 11:26 pm
Hola soy nuevo en esto y he visto probado el ejemplo y algunos cambios, pero hasta ahora no se cómo se hace el insert… agradecería una ayuda…
October 3, 2010 a las 4:03 pm
Hola. HE probado el codigo pero no me carga los datos de la tabla
. tengo bien configurado la librería de pdo y estoy trabajando con php 5. ¿Qué falta por configurar?
October 13, 2010 a las 1:12 pm
Hola!
Federico esta muy interesante tu tutorial, y de hecho he incluido algunas librerías adicionales para ir mejorando el modelo, pero; como soy nuevo en esto, he intentado modificar que, no halla necesidad de instanciar el modelo cada que necesite realizar una consulta.
por ejemplo en tu codigo
listadoTotal();
//Pasamos a la vista toda la información que se desea representar
$data['listado'] = $listado;
//Finalmente presentamos nuestra plantilla
$this->view->show(“listar.php”, $data);
}
public function agregar()
{
echo ‘Aqui incluiremos nuestro formulario para insertar items’;
}
}
?>
me gustaria que no tubiece que incluir el archivo require ‘models/ItemsModel.php’; sino que se hiciese automaticamente como funciona en algunos mvc en los que he trabajado.
sino que atravez de una variable por ejemplo $model->listadoTotal() pudiese llamar mis consultas,
he intentado hacerlo en el frontController de la siguiente forma pero no se como seguir; me puedes ayudar??
‘ . $actionName . ‘` no existe’, E_USER_NOTICE);
return false;
}
//Si todo esta bien, creamos una instancia del controlador y llamamos a la accion
$controller = new $controllerName();
$controller->$actionName();
$model = new $modelName();
return true;
}
}
?>
gracias por tu ayuda
PD => esta muy bakano tu tutorial
December 6, 2010 a las 10:05 am
gracias por el ejemplo esta muy bueno, mi pregunta es si en una vista nesecitas mostrar datos de varias tablas, que normalmente en consulta se usaria left join, que se hace en estos casos?
saludos
Marco
December 6, 2010 a las 6:51 pm
Buenas,
Enhorabuena por este pequeño MVC que hiciste para que tod@s aprendieramos… de verdad, estoy agradecido
Bueno veamos, resulta que estoy intentando aprender MVC y me estoy guiando con tu ejemplo…
La cuestión es que por ahora funciona bien, no tengo ningun problema, excepto que no se como puedo pasarle varios parametros.
Me explico. Supongamos que tengo esto:
http://www.web.com/?controlador=Usuarios&accion=listar
Accediendo de esa manera se ven todos los usuarios. Hasta ahí todo bien.
Pero… ¿y si quiero ver un usuario especifico? o, ¿y si quiero pasar dos parametros mas?
Ejemplo:
http://www.web.com/?controlador=Usuarios&accion=listar&id_usuario=15
http://www.web.com/?controlador=Usuarios&accion=listar&id_usuario=15&bar=foo
¿Cómo podría hacer eso?
Muchas gracias
December 7, 2010 a las 9:12 am
Buenas de nuevo… ya conseguí pasar varios parametros…
Ahora tengo un problema y es que necesito consultar dos tablas y con PDO no sé como se hace.
Veamos, en el modelo tengo una sencilla consulta (como el ejemplo de este blog), donde muestro TODAS las noticias de una base de datos.
Lo que hace es mostrar TODAS las noticias. La cuestión es que cada noticia tiene un user_id.
Entonces, debo de pasar esa id de usuario a la tabla usuarios para que junto a la noticia me muestre el nombre/nick de usuario y no su id.
¿se entiende?
Por tanto, el problema que tengo es que no se hacer esa segunda consulta.
Muchas gracias,
}
?>
December 17, 2010 a las 12:59 am
Hola, Buenos dias, excelente tutorial y felicidades por ello.
Pero hay algo que no me queda muy claro, y quisiera ver si pudieran aclararme la duda.
Como llamo un Controlador desde un formulario html?,
Muchas gracias.
Saludos!!
December 17, 2010 a las 1:04 am
Holas, nuevamente. solo aclarando algo que no me salio en la consulta anterior.
La duda es la siguiente:
form method=”post” action=”{Como llamo aqui al controlador}”
O cual es la manera correcta?
Gracias
January 19, 2011 a las 9:45 am
Maestro, sensei, gurú, ídolo, chacal, eminencia, chaman, doctor, erudito, experto, licenciado…
Simplemente gracias…
En estos artículos he aprendido mas que en cualquier web, sobre todo por los ejemplos, se agradece.
Saludos desde Chile
January 28, 2011 a las 9:36 am
Saludos
me gustaria saber de que forma implementar el modelo MVC con ajax(jquery)?
te lo agradeceria mucho
February 2, 2011 a las 4:05 pm
Hola, tengo una consulta:
En el ejemplo2, en el archivo listar.php, hay alguna manera de listar los items que no se con el fetch()?
no uso PDO por eso no me sirve, he probado con foreach pero me da error.
En mi sistema, la variable $listado que se le pasa a la view es un array de objetos Item, los cuales tienen sus metodos get para obtener los datos.
Probé las siguientes cosas y no entiendo porque me da error:
- echo $listado[0];
ERROR:
Catchable fatal error: Object of class Item could not be converted to string
- echo $listado[0]->get_id_item();
ERROR:
Call to a member function get_id_item() on a non-object
Alguien sabe que puede estar pasando?
Muchas gracias.
February 2, 2011 a las 4:29 pm
Ya solucioné mi error!! Escribí código donde no iba y me generaba un error! gracias igual.
Buenísimo el ejemplo y la explicación me ayudó a entender lo del mvc!!
Gracias!
March 2, 2011 a las 11:27 pm
Federico:
Excelente par de tutoriales. Me hubiera gustado tener mas maestros ke explicaran como tu lo haces. Animate a escribir un libro sobre MVC. Jquery se utiliza bastante hoy en dia, la tercera parte de este articulo podria ser la implementacion de Ajax.
March 5, 2011 a las 9:46 am
Buenos días,
He probado la estructura que propones y me parece perfecta para implementarla en un nuevo proyecto. Todo iba estupendamente hasta que usando PDO tuve que hacer uso del método lastInsertId para recuperar el id después de hacer un INSERT con PDO. Me da un error documentado como que ese método no está implementado para mi controlador. Esto me ha hecho dudar del uso de PDO y hacer uso de otra clase que encontré llamada adodb (http://adodb.sourceforge.net/). ¿Podrías echarme una mano de cómo implementar singleton en el proyecto en lugar de PDO?. Soy nuevo en esto de las clases y me he quedado pegado.
Un saludo y muchas gracias.
May 27, 2011 a las 7:40 pm
Saludos a todos:
Estoy empezando en PHP+MVC y estoy siguiendo este tutorial para empezar.. mi duda esta en como Insertar un registro ingresados desde un formulario y tambien la Actualizacion de la misma. ya llevo varios dias tratando de dar solucion pero nada… a ver si me pueden dar la mano.
June 8, 2011 a las 1:52 pm
Normalmente obtengo documentación, cuando busco algo por inet.
Pese al tiempo del artículo, aquí no he obtenido documentación, sino que ha sido una pequeña gran clase magistral, por su sencillez y robustez.
Excelente artículo =)
Un saludo!!!
October 20, 2011 a las 10:55 pm
Muchas gracias… Por este valioso aporte… he aprendido muchisimo con estos ejemplos tuyos. Mi pregunta es ¿El modelo puede capturar datos directamente variables $_GET desde la URL?
Bueno poder se puede pero es la forma correcta de hacerlo, o todas esas variables tienen que pasarse solo por el controlador?
Espero me puedas responder gracias.
October 21, 2011 a las 1:45 pm
Me parece un tutorial muy claro y completo, muchas gracias por tomarte el tiempo de escribirlo y compartirlo.
October 26, 2011 a las 1:17 pm
Hey, gracias por estos articulos, si que son valiosos, he aprendido muchos con tus aportes, ahora mi pregunta es: ¿El modelo puede recibir datos directamente por $_GET?
Espero puedas responderme.
Gracias.
November 24, 2011 a las 6:17 pm
Hola Fede! tengo una pregunta para vos que me esta complicando demasiado…
Implemente el modelo MVC en base al segundo ejemplo (el mas completo), pero tengo un problema. Te comento como viene el tema.
Mediante post y ajax llamo al controlador y realizo dos consultas al controlador que este a su vez va al modelo y finalmente a la base de datos. El problema es que si en un metodo del controlador llamo a dos metodos del modelo, no me ejecuta el segundo, no se si tiene que ver con el tema del singleton o no. Pero he hecho varias pruebas y siempre me funciona solo la primer consulta. Como podria solucionar esto?
Gracias!
November 24, 2011 a las 6:37 pm
Veo que fuimos varios los que cometimos el mismo error con el singleton de la base de datos… @Victor, @Fede me podrian ayudar?
Comente este if, pero igualmente sigo teniendo el mismo problema
public static function singleton()
{
if( self::$instance == null )
{
self::$instance = new self();
}
return self::$instance;
}
November 27, 2011 a las 4:51 am
disculpa la molestia, por cierto excelente tutorial… una consulta , me sale este error :
Fatal error: Class ‘PDO’ not found in C:\AppServ\www\prueba2\modelos\itemsModelo.php on line 3
espero tu pronta respuesta . gracias
December 12, 2011 a las 2:23 pm
Gracias por el tutorial, muy bueno
December 21, 2011 a las 7:47 pm
Hola, seria bueno que a penas tuvieras tiempo publicaras la manera de como agregar un item, es decir el controlador que respuesta recibe del modelo una vez guarda el registro y como muestras de nuevo la vista.
Gracias.