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

Articulos Relacionados

55 comentarios en “Introducción a MVC con PHP, segunda parte”

  1. imzyos Dijo:

    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 ^^

  2. Federico Dijo:

    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.

  3. imzyos Dijo:

    síp, a eso me referia cuando decia que solo se podia usar para dos cosas, y el que te sigue es Google Reader ^^

  4. Sergio Armando Dijo:

    Exelente explicacion tenia algunos meses esperando esta segunda para muy bueno espero sigas poniendo articulo ya que lo explicas muy … muchas gracias.

  5. Federico Dijo:

    Gracias por tu comentario Sergio :D

  6. mecano Dijo:

    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…. ?

  7. Federico Dijo:

    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

  8. mecano Dijo:

    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.

  9. mecano Dijo:

    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…..

  10. lucas Dijo:

    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

  11. Federico Dijo:

    @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

  12. mecano Dijo:

    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

  13. Jorge Dijo:

    Simplemente felicitarte por tu página es excelente.
    Un saludo

  14. mashter Dijo:

    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

  15. Federico Dijo:

    @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.

  16. lucas Dijo:

    como seria el singleton para usar la conxion a mysql comun que se hace con php sin usar ningun liberia?

  17. lucas Dijo:

    hola otra consulta:
    como puedo hacer para que el error de no se encuentra el controlador salga en el template?

    salu2

  18. Federico Dijo:

    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

  19. gerardo Dijo:

    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

  20. Osvaldo Dijo:

    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.

  21. Norter Dijo:

    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.

  22. Federico Dijo:

    Te agradezco mucho el comentario y tu visita Norter :-)

  23. Sule Dijo:

    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.

  24. Marcelo Dijo:

    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

  25. palotex Dijo:

    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.

  26. Federico Dijo:

    Gracias por sus comentarios gente :-D

    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

  27. Veronica Dijo:

    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

  28. Federico Dijo:

    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!

  29. verito Dijo:

    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.

  30. Federico Dijo:

    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

  31. Javier Dijo:

    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.

  32. Jorge_jrs Dijo:

    Hola federico
    Muy bueno el tutorial, y mucho mejor con el ejemplo. Me esta ayudando en gran manera.
    Saludos

  33. Federico Dijo:

    @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.

  34. Victor Dijo:

    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?

  35. Federico Dijo:

    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

  36. manual Dijo:

    public static function singleton()
    {
    if (!isset(self::$instance)) {
    $c = __CLASS__;
    self::$instance = new $c;
    }

    return self::$instance;
    }

    ¿que significa _CLASS_ en ese codigo?

  37. Federico Dijo:

    Hola, __CLASS__ es una constante que indica el nombre de la clase actual, mas info y ejemplos.

    Saludos

  38. Sergio Armando Dijo:

    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

  39. Adrian Dijo:

    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

  40. Federico Dijo:

    @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?

  41. Martin Dijo:

    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.

  42. Raul Dijo:

    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

  43. Victor Dijo:

    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.

  44. Victor Dijo:

    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

  45. Federico Dijo:

    @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.

  46. Victor Dijo:

    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.

  47. Federico Dijo:

    @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

  48. Wolfmarel Dijo:

    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)

  49. El Tiliche Dijo:

    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…

  50. lucas Dijo:

    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

  51. Federico Dijo:

    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

  52. Luis Dijo:

    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

  53. lucas Dijo:

    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

  54. Federico Dijo:

    @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

  55. Luis Dijo:

    Era eso Federico, muchas gracias, otra consulta, tendrias un ejemplo sobre el manejo de clase Router y una de login implementando este estema?

Deja tu comentario

XHTML: Puedes usar estos tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

El blog funciona con Wordpress y Simpla theme