php patron mvc

Upload: xtywo

Post on 16-Jul-2015

731 views

Category:

Documents


3 download

TRANSCRIPT

http://net.tutsplus.com/tutorials/php/real-world-oop-with-php-and-mysql/Real-World OOP With PHP and MySQL Angelo Rodrigues on Nov 26th 2008 with 196 comments Numerous examples from robots to bicycles have been offered as easy explanations of what OOP is. Ive opted to show you how OOP works with a real-life example, for a programmer. By creating a MySQL CRUD class you can easily create, read, update and delete entries in any of your projects, regardless of how the database is designed.

Setting up the skeleton of our class is fairly simple once we figure out exactly what we need. First we need to make sure that we can do our basic MySQL functions. In order to do this, we need the following functions: Select Insert Delete Update Connect Disconnect

DatabaseThose seem pretty basic, but Im sure that as we go through, well notice that a lot of them utilize some similar aspects, so we may have to create more classes. Here is what your class definition should look like. Notice that I made sure that the methods were created with the public keyword.

class Database { public function connect() { public function disconnect() public function select() } { { } }

public function insert() public function delete() public function update() } {

{ { }

} }

function connect()This function will be fairly basic, but creating it will require us to first create a few variables. Since we want to make sure that they cant be accessed from outside our class, we will be setting them as private. These variables will be used to store the host, username, password and database for the connection. Since they will pretty much remain constant throughout, we dont even need to create modifier or accessor methods for it. After that, wed just need to create a simple mysql statement to connect to the database. Of course, since as programmers we always have to assume the user (even if it is us) will do something stupid, lets add an extra layer of precaution. We can check if the user has actually connected to the database first, and if they have, there really isnt a need to re-connect. If they havent then we can use their credentials to connect.

private db_host = ; private db_user = ; private db_pass = ; private db_name = ;

public function connect() { if(!$this->con) { $myconn = @mysql_connect($this->db_host,$this->db_user,$this>db_pass); if($myconn)

{ $seldb = @mysql_select_db($this->db_name,$myconn); if($seldb) { $this->con = true; return true; } else { return false; } } else { return false; } } else { return true; } } As you can see, it makes use of some basic mysql functions and a bit of error checking to make sure that things are going according to plan. If it connects to the database successfully it will return true, and if not, it will return false. As an added bonus it will also set the connection variable to true if the connection was successfully complete.

public function disconnect()

This function will simply check our connection variable to see if it is set to true. If it is, that means that it is connected to the database, and our script will disconnect and return true. If not, then there really isnt a need to do anything at all.

public function disconnect() { if($this->con) { if(@mysql_close()) { $this->con = false; return true; } else { return false; } } }

public function select()This is the first function where things begin to get a little complicated. Now we will be dealing with user arguments and returning the results properly. Since we dont necessarily want to be able to use the results right away were also going to introduce a new variable called result, which will store the results properly. Apart from that were also going to create a new function that checks to see if a particular

table exists in the database. Since all of our CRUD operations will require this, it makes more sense to create it separately rather than integrating it into the function. In this way, well save space in our code and as such, well be able to better optimize things later on. Before we go into the actual select statement, here is the tableExists function and the private results variable.

private $result = array();

private function tableExists($table) { $tablesInDb = @mysql_query('SHOW TABLES FROM '.$this->db_name.' LIKE "'.$table.'"'); if($tablesInDb) { if(mysql_num_rows($tablesInDb)==1) { return true; } else { return false; } } } This function simply checks the database to see if the required table already exists. If it does it will return true and if not, it will return false.

public function select($table, $rows = '*', $where = null, $order = null) { $q = 'SELECT '.$rows.' FROM '.$table; if($where != null) $q .= ' WHERE '.$where; if($order != null) $q .= ' ORDER BY '.$order; if($this->tableExists($table)) { $query = @mysql_query($q); if($query) { $this->numResults = mysql_num_rows($query); for($i = 0; $i < $this->numResults; $i++) { $r = mysql_fetch_array($query); $key = array_keys($r); for($x = 0; $x < count($key); $x++) { // Sanitizes keys so only alphavalues are allowed if(!is_int($key[$x])) { if(mysql_num_rows($query) > 1)

$this->result[$i][$key[$x]] = $r[$key[$x]]; else if(mysql_num_rows($query) < 1) $this->result = null; else $this->result[$key[$x]] = $r[$key[$x]]; } } } return true; } else { return false; } } else return false; } While it does seem a little scary at first glance, this function really does a whole bunch of things. First off it accepts 4 arguments, 1 of which is required. The table name is the only thing that you need to pass to the function in order to get results back. However, if you want to customize it a bit more, you can do so by adding which rows will be pulled from the database, and you can even add a where and order clause. Of course, as long as you pass the first value, the result will default to their preset ones, so you dont have to worry about setting all of them. The bit of code right after the arguments just serves to compile all our arguments into a select statement. Once that is done ,a check is done to see if the table exists, using our prior tableExists function. If it exists, then the function continues onwards and the query is performed. If not, it will fail.

The next section is the real magic of the code. What it does is gather the columns and data that was requested from the database. It then assigns it to our result variable. However, to make it easier for the end user, instead of auto-incrementing numeric keys, the names of the columns are used. In case you get more than one result each row that is returned is stored with a two dimensional array, with the first key being numerical and auto-incrementing, and the second key being the name of the column. If only one result is returned, then a one dimensional array is created with the keys being the columns. If no results are turned then the result variable is set to null. As I said earlier, it seems a bit confusing, but once you break things down into their individual sections, you can see that they are fairly simple and straightforward.

public function insert()This function is a lot simpler than our prior one. It simply allows us to insert information into the database. As such we will require an additional argument to the name of the table. We will require a variable that corresponds to the values we wish to input. We can simply separate each value with a comma. Then, all we need to do is quickly check to see if our tableExists, and then build the insert statement by manipulating our arguments to form an insert statement. Then we just run our query.

public function insert($table,$values,$rows = null) { if($this->tableExists($table)) { $insert = 'INSERT INTO '.$table; if($rows != null) { $insert .= ' ('.$rows.')';

}

for($i = 0; $i < count($values); $i++) { if(is_string($values[$i])) $values[$i] = '"'.$values[$i].'"'; } $values = implode(',',$values); $insert .= ' VALUES ('.$values.')'; $ins = @mysql_query($insert); if($ins) { return true; } else { return false; } } } As you can see, this function is a lot simpler than our rather complex select statement. Our delete function will actually be even simpler.

public function delete()

This function simply deletes either a table or a row from our database. As such we must pass the table name and an optional where clause. The where clause will let us know if we need to delete a row or the whole table. If the where clause is passed, that means that entries that match will need to be deleted. After we figure all that out, its just a matter of compiling our delete statement and running the query.

public function delete($table,$where = null) { if($this->tableExists($table)) { if($where == null) { $delete = 'DELETE '.$table; } else { $delete = 'DELETE FROM '.$table.' WHERE '.$where; } $del = @mysql_query($delete);

if($del) { return true; } else

{ return false; } } else { return false; } }

And finally we get to our last major function. This function simply serves to update a row in the database with some new information. However, because of the slightly more complex nature of it, it will come off as a bit larger and infinitely more confusing. Never fear, it follows much of the same pattern of our previous function. First it will use our arguments to create an update statement. It will then proceed to check the database to make sure that the tableExists. If it exists, it will simply update the appropriate row. The hard part, of course, comes when we try and create the update statement. Since the update statement has rules for multiple entry updating (IE different columns in the same row via the cunning use of commas), we will need to take that into account and create a way to deal with it. I have opted to pass the where clause as a single array. The first element in the array will be the name of the column being updated, and the next will be the value of the column. In this way, every even number (including 0) will be the column name, and every odd number will be the new value. The code for performing this is very simple, and is presented below outside the function:

for($i = 0; $i < count($where); $i++) { if($i%2 != 0) {

if(is_string($where[$i])) { if(($i+1) != null) $where[$i] = '"'.$where[$i].'" AND '; else $where[$i] = '"'.$where[$i].'"'; } else { if(($i+1) != null) $where[$i] = $where[$i]. ' AND '; else $where[$i] = $where[$i]; } } } The next section will create the part of the update statement that deals with actually setting the variables. Since you can change any number of values, I opted to go with an array where the key is the column and the value is the new value of the column. This way we can even do a check to see how many different values were passed to be updated and can add commas appropriately.

$keys = array_keys($rows); for($i = 0; $i < count($rows); $i++) { if(is_string($rows[$keys[$i]]))

{ $update .= $keys[$i].'="'.$rows[$keys[$i]].'"'; } else { $update .= $keys[$i].'='.$rows[$keys[$i]]; } // Parse to add commas if($i != count($rows)-1) { $update .= ','; } }

function update()Now that weve got those two bits of logic out of the way, the rest of the update statement is easy. Here it is presented below:

public function update($table,$rows,$where) { if($this->tableExists($table)) { // Parse the where values // even values (including 0) contain the where rows // odd values contain the clauses for the row for($i = 0; $i < count($where); $i++)

{ if($i%2 != 0) { if(is_string($where[$i])) { if(($i+1) != null) $where[$i] = '"'.$where[$i].'" AND '; else $where[$i] = '"'.$where[$i].'"'; } } } $where = implode('=',$where);

$update = 'UPDATE '.$table.' SET '; $keys = array_keys($rows); for($i = 0; $i < count($rows); $i++) { if(is_string($rows[$keys[$i]])) { $update .= $keys[$i].'="'.$rows[$keys[$i]].'"'; } else { $update .= $keys[$i].'='.$rows[$keys[$i]];

}

// Parse to add commas if($i != count($rows)-1) { $update .= ','; } } $update .= ' WHERE '.$where; $query = @mysql_query($update); if($query) { return true; } else { return false; } } else { return false; } }

Now that we have that weve finished our last function, our simple CRUD interface for MySQL is complete. You can now create new entries, read specific entries from the database, update entries and delete things. Also, be creating and reusing this class youll find that you are saving yourself a lot of time and coding. Ah, the beauty of object oriented programming.

The UseSo we've got our class all made, but how do we use it? This part is simple. Lets start by creating a very simple system database to use in our testing. I created a database called test, and then ran the MySQL statment. You can place it in any database that you like, just make sure that you change the connection variables at the top of the script to match:

The first line is commented out simply because not everyone will need it. If you need to run that more than once, you will need to uncomment it the second time to ensure that it creates the table.

Now that our table is created and populated, it's time to run a few simple queries on it.

&lt?php; include('crud.php'); $db = new Database(); $db->connect(); $db->select('mysqlcrud'); $res = $db->getResult(); print_r($res); ?> If done correctly, you should see the following:

Likewise we can go a step further and run an update query, and then output the results:

&lt?php; $db->update('mysqlcrud',array('name'=>'Changed!'),array('id',1)); $db->update('mysqlcrud',array('name'=>'Changed2!'),array('id',2)); $res = $db->getResult(); print_r($res); ?> We should see this

Now for a simple insert statement:

;&lt?php; $db->insert('mysqlcrud',array(3,"Name 4","[email protected]")); $res = $db->getResult(); print_r($res); ?>

http://web2development.blogspot.com/

BienvenidaBienvenidos a mi blog, la idea de este blog es poner trucos y tips para realizar aplicaciones Web2.0 usando PHP5 y Javascript.

Mucho del potencial de este blog se basara en tips de como hacer las cosas de la forma mas correcta, orientarnos a resolver el problema y aprender a resolver problemas similares en un futuro. Tambin aprovechare para ir poniendo partes del cdigo de mi framework sobre el que se basaran algunas de las soluciones. Aunque no todo sera programacin, tambin se publicaran cosas chistosas y noticias en general, espero puedan tener una lectura de su agrado, no se olviden de comentar si no les parece algo, todos tienen su derecho de replica.

JSON: Transferir objetos entre PHP y JavascriptEn la semana estuve buscando varias formas de establecer una comunicacin entre PHP y una pagina HTML, casi 100% JavaScript. La idea era reutilizar ya varios componentes que existen, entre ellos prototype una librera que implementa JSON de una forma casi nativa (desde su versin 1.5). Me encontr con varias complicaciones, y que seguramente te puedes encontrar, una de ellas es enviar directamente el objeto JSON y recibirlo en Javascript de forma nativa, el problema de esto es que para hacerlo debe de estar enviado en el header como X-JSON, y como contenido el objeto JSON. La limitante de esto es que hay un limite (para Internet Explorer) en la cantidad de datos que puede enviar por el header X-JSON, asi que si vas a enviar un objeto muy largo te recomiendo que lo enves directamente en el body de tu contenido. Ahora al tutorial, desde la version 5.2, PHP incorpora una extension nativa para codificiar objetos, arrays, variables, etc. a JSON, es mas recomendable usar esta funcion (pues esta programada en C y su velocidad es mucho mayor a la clase en PHP). Para empezar creamos nuestro objeto en PHP, que vamos a enviar a Javascript, es algo sencillo:

class Persona { public $nombre; public $apellido; public $edad; public function __construct($nombre, $apellido, $edad ) { $this->nombre = $nombre;

$this->apellido = $apellido; $this->edad = $edad; } }

Este es un objeto bsico, pero eficiente, los atributos pblicos son los que se van a enviar y codificar como JSON, si no deseas tener atributos pblicos, puedes implementar tu propio mtodo que te regrese las variables privadas ya codificadas. Esto lo mostrare en un tutorial mas adelante. Este objeto nos sirve para almacenar el nombre, el apellido y la edad de una persona. Bonito, ahora como lo podemos enviar a JavaScript y mantener que sea un objeto de tal forma que lo podamos leer as:

function verPersona( persona ) { var nombre = persona.nombre; var apellido = persona.apellido; var edad = persona.edad; }

La solucion es usar AJAX y Protototype, primero creamos nuestro script en PHP:

require( "Persona.php" ); // Hacemos un request a una base de datos, etc. $persona = new Persona($nombre, $apellido, $edad); header("Content-type: application/json"); echo "(" . json_encode( $persona ) . ")";

Si quieres enviarlo en el header para que prototype lo cree automtico haces esto: header( "X-JSON: (" . json_encode($persona) . ")");

Es importante enviarlo entre parntesis para que en JavaScript no tengas problemas, para recibirlo haces un request:

function getPersona() { var ajax = new Ajax.Request( '/myscript.php', { method: 'get', onComplete: checkResponse } ); }

function checkResponse( transport, json ) { // Si enviaste como el header X-JSON, tu objeto ya esta en json de lo contrario haz esto: json = tranport.responseText.evalJSON(true); alert( Object.inspect(json) ); }

Ya en tu variable json tienes un objeto que puedes utilizar para sacar tus propiedades. Espero que con este tutorial puedas enviar y recibir objetos de forma nativa desde PHP y hacia Javascript, las ventajas de usar JSON sobre AJAX es que JSON es mucho mas liviano para JavaScript. No es necesario parsear XML y el ancho de banda usado es menor. Ahora a codificar aplicaciones Web2.0 mucho mas sencillo.

Accesando a nuestra base de datos con PDOPHP y MySQL, se llevan de la mano, es muy sencillo y casi todos los paquetes "todo en uno" implementan PHP y MySQL, esto le dio a PHP una ventaja muy grande y un crecimiento muy grande. El problema viene que muchos programadores inexpertos se pusieron a programar, y a hacer micro sistemas, o scripts, que en si sirven para su funcin, pero pueden llegar a ser inseguros y los hackers empiezan a buscar agujeros para explotar sus funciones y poder entrar a la base de datos y borrar, o cambiar todo. Este es un problema grave (investiguen el caso de PHP-Nuke o PHPBB en sus primeras versiones), ya que programando webs inseguras, ocurren varias cosas, nos vemos mal como programadores, y damos mala fama a todos los programadores web. Para evitar esto hay que ser extremadamente cuidadosos en las variables que enviamos para entrar a la base de datos, dichas variables SIEMPRE tienen que ser verificadas que son los datos que esperamos, en pocas palabras existe una regla de oro: Nunca confes en el contenido que te enva el usuario Como podemos remediarlo? Puede ser un dolor de cabeza, pero en cada variable que enves tienes que checar si esta activado o no magic_quotes (otro error en PHP que por defecto viene activado), luego escapar todos tus strings con addslashes ymysql_real_escape_string, luego checar tus querys y ver que no permitas ningn agujero en tu cdigo.

Esto es un dolor de cabeza pero es necesario, ahora, que pasa si derrepente te cambian tu base de datos, que pasa si tu cliente en lugar de mysql, decide que quiere MSSQL o PostgreSQL. Tendras ahora mas dolores de cabeza, para remediar esto, y para evitar programar mal desde la version 5.1 de PHP viene por defecto (y activado) PDO. PDO por sus siglas en Ingles (PHP Data Objects) Objetos de Datos de PHP. PDO es un driver de acceso a varias bases de datos por lo que es ideal que cuando empieces a programar lo hagas sobre este driver. Este pequeo mini tutorial te dir como entrar, seleccionar, insertar y actualizar datos en tu base de datos favorita: MySQL, si requieres cambiar a otra base de datos, por lo general solo cambiaras una linea de tu cdigo. Como conectar a MySQL Para iniciar una conexin a MySQL usamos el constructor PDO: try { $db = new PDO('mysql:dbname=testdb;host=localhost', $user,$pass); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Cerramos la conexion $db = null; } catch( PDOException $e ) { echo "Error de conexion: " . $e->getMessage(); }

Facil, no utilizamos ni mysql_connect, ni mysql_close, el constructor PDO nos crea una instancia del driver sobre el que podemos trabajar. Toda instancia de PDO si le pasamos como atributo que PDO::ERRMODE_EXCEPTION lanzara una excepcion en cuanto tenga un error, esto es muy util ya que nos concentraremos en realizar el trabajo, y si de paso estamos usando transacciones, si hay una excepcion automaticamente son regresadas garantizando que nuestros datos sean consistentes. Ahora enviar querys, es sencillo, ya que automticamente las variables son protegidas contra ataques de SQL Inyection. Aqu si cambia un poco la forma, ya que usamos lo que se le conoce como Prepared Statements o Comandos Preparados, es igual de sencillo, cuando preparamos un query (ya sea Insert, Select, Update, Call, etc.). La forma es sencillo:

try { $db = new PDO('mysql:dbname=testdb;host=localhost', $user,$pass); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Preparamos un Query $comando = $db->prepare("SELECT * FROM Clientes WHERE Cliente LIKE ?"); // Obtenemos el comando desde GET $cliente = '%' . $_GET['Cliente'] . '%'; $comando->execute( array( $cliente ) ); while( $row = $comando->fetch() ) { var_dump( $row ); // Imprimimos resultados } // Cerramos la conexion $comando = null; $db = null; } catch( PDOException $e ) { echo "Error de conexin: " . $e->getMessage(); } Como podemos ver, podemos usar directamente el valor de nuestro $_GET sin temor a que sea una cadena que pueda perjudicarnos, ya que el driver automticamente se encarga de analizar y enviar la cadena como un string. Si vemos el query hay algo diferente y es el uso de lo que se le conoce como marcadores o "placeholders", esto es el signo de interrogacin en el WHERE "?". Estos marcadores es lo que se va a reemplazar por el valor que tu le asignes cuando uses execute(). Para actualizar solo debes de cambiar tu Query: UPDATE Clientes SET Nombre=? WHERE idCliente=? Y enviar tu query: $comando->execute( array( "Juan", 1 ); Como puedes ver, no es necesario escapar las variables, ni mucho menos, esto te da la facilidad, y te quita una preocupacin. Otra ventaja de usar PDO en lugar de las funciones de mysql normales, es que podemos extenderlas y crear nuestra propia clase de bases de datos, agregarle el patron Singleton y tener ya lista una clase para trabajar con nuestro sistema.

Un rapido ejemplo: class DB extends PDO { private static $_instance = null; private function __construct() { // Obtenemos el Config desde un array, clase config etc: $config = Config::getInstance(); $db = $config->DBName; $user = $config->UserName; $pwd = $config->Password; $attrs = array(); $dsn = 'mysql:host=localhost;dbname=' . $db; parent::__construct( $dsn, $user, $pwd, $attrs ); $this->setAtribute( PDO::ATTR_ERRMODE, PDO::ERR_MODE_EXCEPTION); } public static function getInstance() { if( self::$_instance == null ) { self::$_instance = new self(); } return self::$_instance; } } Espero que con este tutorial te puedas dar una idea de las ventajas de usar PDO en lugar de las funciones de mysql normales, y de paso abrirte camino a la abstraccin de datos.

Patron ActiveTable y ActiveRecordPatrn ActiveTable y ActiveRecord Cuando empezamos a utilizar OOP al 100% empezamos a usar clases para representar objetos que estamos utilizando en el diseo de nuestro sistema. Pensemos en un ejemplo bsico, vamos a hacer un catalogo de automviles, para representar a nuestro automvil vamos a utilizar la siguiente clase:

1

Como podemos ver nuestro automvil tiene propiedades bsicas, puede ser ms complejo pero para este tutorial lo dejaremos as. Podemos utilizar nuestro nuevo objeto Automvil de la siguiente manera:

1 2 3 4 5 6 7

Es muy sencillo, pero se complica cuando queremos que este automvil sea persistente, o sea que este guardado en un medio no voltil, como una base de datos, XML, archivo de texto, etc. Esto es fcil de implementar, por ejemplo usando serialize y guardndolo en esos medios, pero cmo lo recuperamos?, Cmo podemos hacer bsqueda por cierta caracterstica (ej: el color)? Aqu es donde se complica todo, ya que si queremos tener una tabla en nuestra base de datos donde cada propiedad de nuestra clase represente una columna de nuestra base de datos, y cada instancia de la clase represente una fila de nuestra tabla necesitamos de cierta forma hacer que se traduzca la clase en un objeto que se pueda insertar en nuestra base de datos. La forma de hacer esto: ActiveRecord, este es un patrn de diseo, con el cual podemos implementar de manera correcta que cada objeto nos represente una fila de nuestra base de datos. Qu es el ActiveTable?

El Active Table es un objeto que puede persistir otros objetos en medios no voltiles, como bases de datos. La funcin de una clase que implementa este patrn es de comunicarse con la base de datos y regresarnos objetos como los tenemos definidos para nuestra aplicacin. Veamos el siguiente ejemplo:

1 2 3 4 5 6 7

Como podemos ver, nuestro ActiveTable Automviles nos trae un objeto automvil, sobre el cual podemos trabajar e incluso guardar directamente en la base de datos, el objeto es lo suficientemente inteligente para saber guardarse o crear uno nuevo. Cmo implementamos este patrn? Hay varias formas de implementarlo, muchos Frameworks lo hacen a su manera, yo en lo personal me gusta la siguiente forma, en la que heredando la clase directamente, podemos saber el nombre de la tabla y usamos comandos simples para obtener los datos que nos interesan (como la clave primaria). Una vez creado nuestro objeto, a la hora de pedirle que nos regrese algo (con alguna de las funciones find*), la clase debe de crear y regresarnos un objeto que podamos utilizar (en nuestro caso un objeto Automvil). Este objeto nos sirve para trabajar como lo vimos en el primer ejemplo, pero tambin a la hora de implementar ActiveRecord es posible que el objeto se sepa guardar en la base de datos solos. Veamos el siguiente ejemplo de ActiveTable:

1 2 3 4 5 6 7

Como podemos ver, no usamos 1 sola sentencia SQL directamente, esto nos permite tener un nivel de abstraccin muchsimo mayor e inclusive a la hora de programar es mucho ms rpido. De aqu faltan mucho ms cosas, como por ejemplo hace unos meses en ForosDelWeb alguien deca que esto no era efectivo porque cuando tenemos claves forneas, tenamos que crear dos instancias y las clases hacan mltiples consultas a la base de datos, esto es cierto, pero no totalmente, podemos modificar nuestra clase para que sea lo suficientemente inteligente y pueda resolver las claves forneas, y crear Joins, esto es ms complicado y no se va a cubrir en este tutorial, pero es posible al 100%, y de manera eficiente. Espero que con este tutorial les haya quedado como implementar estos patrones de diseo y puedan realizar sus aplicaciones ms limpias.

Aqui les dejo un link para que vean como implementar ArrayAccessy como nos permite accesar a las propiedades de un objeto como si fuera un Arreglo.

Publicar codigo PHP en BloggerMuchas veces nos preguntamos como publicar cdigo fuente, en varios blogs hay herramientas para tal efecto, pero en blogger particularmente no hay forma tan sencilla, eso si tenemos todo el poder para poder publicar cdigo HTML directamente. Para eso desarrolle un pequeo script en PHP, cuya finalidad es esa, formatear el codigo PHP y dejarlo listo para que se pueda publicar, con colores y nmeros de lineas. La uncia desventaja es que tienes que copiar el cdigo fuente directamente cuando lo genera el script (delimitado va comentarios). El porque de esto es porque si lo pones en una etiqueta PRE, el browser interpreta el cdigo, al igual que si estuviera en un

textarea. La nica forma de que se quedara formateado y listo era copiando directamente del codigo fuente, as que para utilizar este script, lo que haces es enviar tu cdigo y presionas Enviar, al recargarse la pagina, debes de seleccionar ver cdigo fuente y copiarlo directamente de ah. Espero les sea de ayuda, ya que funciona para publicar cualquier cdigo, pero con colores solo con PHP, aunque se puede expandir para utilizar un sistema mayor de publicacin de cdigo y poder publicar casi cualquier tipo de cdigo en Blogger. Aqu les dejo el cdigo (formateado con el mismo script):

1 20 21 22 Format Code 23 24 25 26

Vista (listado.php): 1 2 3 ID 4 Nombre 5 Color 6 7 8 9 10 11 12 13 14

Modelo: (Automoviles.php) 1

Dispatcher: (este es el unico archivo que no es OOP) 1

Como podemos ver la vista (que no es nada ms que otro PHP) se encarga de imprimir la tabla y dejarla lista para su visualizacin, el modelo solo recibe lo que el controlador le enva y es de donde la vista obtiene su fuente de informacin. Otro ejemplo seria agregar un nuevo automvil a nuestro catalogo de automviles: Controlador (AutomovilesController.php): 1

Vista (nuevoAuto.php): 1 2 3 4 5 6 7 8 9 Nombre: 10 11 12 13 Color: 14 15 16 17 18 19 20 21 22

El Modelo es el mismo que el anterior. Dispatcher: (este es el unico archivo que no es OOP) 1

Este ejemplo es muy bsico, y al patrn MVC se le han agregado muchas cosas, como puede ser un Router que se encargue de decidir que controlador utilizar dependiendo de la entrada de informacin. Otra adicin son los smart-urls estos se encargan de que los urls sean ms amigables, aunque esto no depende enteramente de PHP, pero es una adicin que muchos ocupan a la hora de utilizar este patrn de diseo. Bsicamente el patrn MVC se puede implementar de una manera sencilla, no requiere de grandes cosas y es un beneficio ya que se utiliza mucha OOP, en el prximo artculo pondr un ejemplo de un router sencillo con smart urls para anexar a este patrn de diseo. A continuacin les dejo las clases que se implementaron para el patrn: Controller.php: 1

View.php: 1

mainLayout.php: 1 2 3 Sistema de Autos 4 5 6 7 8

AutomovilesController.php: 1

Espero les ayude a comprender mejor como se utiliza el patrn MVC y como hace que las cosas sean ms flexibles.

FrontControllerSaludos a todos!, antes que nada una disculpa por ya no haber puesto mas temas pero el trabajo me estuvo comiendo. Vuelvo con este tema que es la segunda parte del patrn MVC, y es el FrontController, en el tema pasado vimos como es posible separar la capa de datos/proceso/vista, es una forma ideal para separar nuestro cdigo y hacerlo mucho mas legible. Ahora vamos a ver como centralizar todo y controlar las instancias. En un ambiente como Java o C, siempre hemos tenido dos puntos nicos de entrada, en estos puntos de entrada podemos incluir las clases necesarias, realizar labores de levantamiento, etc. En un ambiente en Web es igual de necesario tener un punto de entrada nico en nuestra aplicacin, as podemos controlar y definir la configuracin de nuestra base de datos, que templates vamos a usar, logs, etc. Aqu podemos ver la utilidad de manejar un punto central de carga, ahora en un ambiente web luego es complicado llegar a esta automatizacin, y otros lenguajes proveen algunas herramientas para facilitar esto (por ejemplo en ASP tenemos el global.asa, etc.). Un FrontController es como la operadora de telfonos que esta en la central que se encargaba en tiempos antiguos de conectar las llamadas entre extensiones, para recordarnos les dejo esta foto:

Esa precisamente es la tarea del FrontController, escucha las peticiones que vienen desde un URL, y se encarga de hacer un dispatch al controlador especifico que mandemos llamar, posteriormente llama a la accin deseada de nuestro controlador, en pocas palabras es un Router de requests, y tiene la facilidad de que al todo ser centralizado podemos hacer tareas de levantamiento. Un ejemplo sencillo de aplicar este patrn seria el siguiente: 1 2 class FrontController { 3 public static function Main() { 4 // Realizamos tareas antes de iniciar el proceso, aqui podemos iniciar lo que sea relativamente... 5 $config = new ConfigBag(); 6 $config['db'] = new ConfigBag(); 7 $config['db']['host'] = "localhost"; 8 $config['db']['user'] = "usuarioDB";

9 $config['db']['password'] = "pass"; 10 $config['db']['database'] = "proyecto"; 11 12 DB::setDefaultConfig( $config['db'] ); 13 ActiveTable::setDefaultDBAdapter( DB::getInstance() ); 14 15 $logFile = "/path/a/log/log.log"; 16 Logger::setDefaultLogger( new FileLogger( $logFile ) ); 17 18 // Definimos nuestro directorio de Controllers 19 $controllerDir = "/path/a/los/controllers/"; 20 // Obtenemos el controlador y la accion 21 $controller = $_GET['controller']; 22 $accion = $_GET['accion']; 23 24 if( empty( $controller ) ) { // Comprobamos si esta vacia, si asi es definimos que por defecto cargue Index 25 $controller = "index"; 26 } 27 if( empty( $accion ) ) { // Comprobamos tambien.. 28 $accion = "index"; 29 } 30 31 $controllerFile = $controllerDir . $controller . ".php"; 32 if( !file_exists( $controllerFile ) ) { // Si no existe el archivo lanzamos una excepcion 33 throw new FrontControllerException( "No se encontro el archivo especificado" ); 34 } 35 36 $controllerClass = $controller . "Controller"; 37 if( class_exists( $controllerClass, false ) ) { // Si existe el archivo pero no esta la clase lanzamos otra excepcion 38 throw new FrontControllerException( "El controlador fue cargado pero no se encontro la clase" ); 39 } 40 41 $controllerInst = new $controllerClass(); 42 43 if( !is_callable( array( $controllerInst, $accion ) ) ) { // Comprobamos si la accion es posible llamarla 44 throw new FrontControllerException( "El controlador no tiene definida la accion $accion" ); 45 } else { 46 $controllerInst->$accion(); // Llamamos a la accion y dejamos el

proceso al controlador 47 } 48 } 49 } 50 51 class FrontControllerException extends Exception {} 52 53 // Iniciamos todo 54 FrontController::Main(); 55 ?>

Como podemos ver el FrontController es un Router que se encarga de enrutar las peticiones, para que esto sea centralizado tenemos que forzosamente llamar al router ej: http://host/router.php?controller=automoviles&accion=listaAutomoviles Ahora con la facilidad que nos da mod_rewrite podemos crear reglas para que nos transforme ese url en algo mas amigable: http://host/automoviles/listaAutomoviles/ Asi podemos pasar los parametros de forma oculta, un ejemplo de esta regla seria: RewriteRule ^(.+)/(.+)/$ router.php?controller=$1&action=$2 Las demas acciones que levanta el FrontController son de ejemplo, asi que podemos ver como centralizar la carga de nuestras clases, en un solo archivo, los includes los podemos realizar de igual manera en nuestros controladores especificando el path completo. Es todo por hoy y espero les sea claro.