Está en la página 1de 16

Utilizando Doctrine como ORM en PHP | Web.

Ontuts

http://web.ontuts.com/tutoriales/utilizando-doctri...

Tutoriales de Desarrollo y Diseo Web | Web.Ontuts


Tutoriales Detallados & Fciles Recursos Iconos, fuentes y ms Inspiracin Despierta tu creatividad Concenos Contacto & Informacin

Utilizando Doctrine como ORM en PHP


julio 6, 2010 en Tutoriales por Ivn Guardado doctrine, orm, php 7 Comentarios Continuamos con otra publicacin perteneciente a la serie de artculos dedicados a Object-Relational Mapping (ORM). Esta vez nos centraremos en algo ms prctico, creando un aplicacin de ejemplo usando Doctrine como

1 de 16

13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts

http://web.ontuts.com/tutoriales/utilizando-doctri...

motor de ORM.
131 Retweet
Share 26

Autor: Ivn Guardado Intentando mejorar cada da en este mundo tan cambiante de la programacin. Sgueme en Twitter o en GitHub. Actualmente estoy disponible para contratar.

Que es Doctrine?
Doctrine es una librera para PHP que nos permite trabajar con un esquema de base de datos como si fuese un conjunto de objetos, y no de tablas y registros. Si no sabes todava que signica ORM y que ventajas / desventajas tiene, te recomiendo que leas el tutorial anterior: Introduccin a Object-Relational Mapping (ORM). Doctrine est inspirado en Hibernate, que es uno de los ORM ms populares y grandes que existen y nos brinda una capa de abstraccin de la base de datos muy completa. La caracterstica ms importante es que te da la posibilidad de escribir consultas de base de datos en un lenguaje propio llamado Doctrine Query Language (DQL).

Caractersticas principales
Doctrine es una librera muy completa y muy congurable, por lo que casi me resulta complicado seleccionar que detalles destacar. Os pongo las caractersticas ms globales, ya que este tutorial pretende ser una introduccin, por lo que dejamos de lado las cosas ms complejas. Generacin automtica del modelo Cuando se trabaja con ORM, necesitas crear el conjunto de clases que representa el modelo de la aplicacin, luego estas clases sern vinculadas al esquema de la base de datos de forma automtica con un motor ORM. Aunque son cosas diferentes, cuando diseas un modelo relacional y un modelo de clases, suelen ser muy parecidos. Doctrine se aprovecha de esta similitud y

2 de 16

13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts

http://web.ontuts.com/tutoriales/utilizando-doctri...

nos permite generar de forma automtica el modelo de clases basndose en el modelo relacional de tablas. Es decir, si tenemos una tabla llamada usuarios, se autogenerar una clase llamada Usuarios cuyas propiedades son las columnas de dicha tabla. Posibilidad de trabajar con YAML Como se comenta en el apartado anterior, Doctrine puede generar de forma automtica el modelo, pero tambin deja la posibilidad (como es lgico) que puedas denir tu mismo el mapeo de tablas y sus relaciones. Esto se puede hacer con cdigo PHP o con YAML, que es un formato de serializacin de datos legible por humanos muy usado para este n. En el ejemplo siguiente se muestra como denir dos tablas relacionadas:
01. 02. 03. 04. 05. 06. 07. 08. 09. 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. --User: columns: username: type: string(255) password: type: string(255) contact_id: type: integer relations: Contact: class: Contact local: contact_id foreign: id foreignAlias: User foreignType: one type: one Contact: columns: first_name: type: string(255) last_name: type: string(255) phone: type: string(255) email: type: string(255) address: type: string(255) relations: User: class: User local: id foreign: contact_id foreignAlias: Contact foreignType: one type: one

3 de 16

13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts

http://web.ontuts.com/tutoriales/utilizando-doctri...

En el ejemplo, se muestra una relacin entre dos tablas a travs de los campos User.contact_id y Contact.id. Doctrine_Record y Doctrine_Table Practicamente todo nuestro modelo heredar de estas dos clases. Doctrine_Record representa una entidad con sus propiedades (columnas) y nos facilita mtodos para insertar, actualizar o eliminar registros entre otros. Por ejemplo:
view plain copy to clipboard print ?

01. 02. 03. 04.

<php $user = new User(); $user->name = Ivn; $user->save();

La clase Doctrine_Table representa el esquema de una tabla. A travs de esta clase podemos, por ejemplo, obtener informacin sobre las columnas o buscar registros especcos:
view plain copy to clipboard print ?

01. 02. 03.

<?php $userTable = Doctrine_Core::getTable('Users'); $user = $userTable->find(1);

Buscadores mgicos (Magic nders) En Doctrine, puedes buscar registros basndote en cualquier campo de una tabla. En el partado anterior podamos ver que existe el mtodo nd() para buscar un determinado id en una tablapues bien, se podra hacer ndByX() en donde X es el nombre de la columna. Si existen los campos llamados name y email, podemos hacer ndByName() y ndByEmail(). Tambien es importante decir que existe el mtodo ndAll(), que obtiene todos los registros de la tabla. Relaciones entre entidades En Doctrine, una vez que hemos denido nuestro modelo (o se ha creado de forma automtica) con las tablas y sus relaciones, resulta fcil acceder y moverse por entidades relacionadas. Vamos a ver un ejemplo de como acceder a valores que en nuestro sistema relacional se encuentran en tablas separadas. Teniendo en cuenta que tenemos dos tablas, User y Comments, con relacin 1-N:
4 de 16 13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts

http://web.ontuts.com/tutoriales/utilizando-doctri...

view plain

copy to clipboard

print

01. 02. 03. 04. 05. 06.

<?php $commentsTable = Doctrine_Core::getTable('Comments'); $comments = $commentsTable->findAll(); foreach($comments as $comment){ echo $comment->User->name; }

A travs de $comment->User estamos accediendo a un nuevo objeto del tipo User que se carga de forma dinmica, de esta forma podemos acceder a las propiedades y mtodos de dicha clase olvidndonos de tener que lanzar cdigo SQL.

Lenguaje DQL
DQL es un lenguaje creado para ayudar al programador a extraer objetos de la base de datos. Entre las ventajas de usar este lenguaje se encuentran: Est diseado para extraer objetos, no las, que es lo que nos interesa. Entiende las relaciones, por lo que no es necesario escribir los joins a mano. Portable con diferentes bases de datos. Es importante considerar el uso de DQL para obtener la informacin a cargar en lugar de usar la forma automtica de Doctrine para mejorar el rendimiento. En el ejemplo anterior, cuando se accede a $comment->User, hemos dicho que se est cargando un nuevo objeto de forma dinmica, pues bien, esto no es ptimo porque realiza consultas SQL de ms. Si tenemos 100 comentarios, ejecutar 100 consultas SQL para cargar la informacin del objeto User, lo cual es una prdida de rendimiento enorme. En lugar de eso, es necesario usar DQL para que traiga toda la informacin de un solo paso:
view plain copy to clipboard print ?

01. 02. 03. 04. 05. 06.

<?php $q = Doctrine_Query::create() ->select('c.*,u.name') ->from('Comments c') ->innerJoin('c.User u'); $comments = $q->execute();

El cdigo anterior obtendr la informacin de los comentarios cruzados con los datos de usuario, por lo que obtendr toda la informacin en un solo paso. El lenguaje DQL es algo tan extenso que necesitara varios artculos para explicarlo en profundidad, por eso te recomiendo que mires la documentacin
5 de 16 13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts

http://web.ontuts.com/tutoriales/utilizando-doctri...

ocial que est bien explicado y completo

Construyendo un ejemplo real


Para darle algo de vida al tutorial, vamos a crear una implementacin muy sencilla de Doctrine en la que veremos todo lo comentado hasta ahora. La aplicacin consiste en un listado de comentarios escritos por usuarios. Cada vez que se desee insertar un nuevo comentario, se deber rellenar un formulario con: nombre, e-mail y texto, siendo los dos ltimos obligatorios. Si el usuario no deja su nombre, se mostrar como Desconocido. Paso 1: crear el esquema de base de datos El ejemplo es tan sencillo que solamente tendr dos tablas relacionadas entre s: users y users_comments.
view plain copy to clipboard print ?

01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13.

CREATE SCHEMA ontuts_doctrine CHARSET UTF8 COLLATE utf8_general_ci; use ontuts_doctrine; CREATE TABLE users( id INT(11) PRIMARY KEY auto_increment, name VARCHAR(30), email VARCHAR(60) )ENGINE=INNODB; CREATE TABLE users_comments( id INT(11) PRIMARY KEY auto_increment, id_user INT(11) NOT NULL, text VARCHAR(255), CONSTRAINT fk_users_comments_users FOREIGN KEY (id_user) REFERENCES users(id) )ENGINE=INNODB;

Paso 2: crear el modelo Esto, como ya habrs aprendido, se puede hacer de forma manual (con PHP o YAML) y de forma automtica. En este caso lo haremos de forma automtica para explicar como funciona. Vamos a crear el script que se encargar de generar los cheros, create_orm_model.php:
view plain copy to clipboard print ?

01. 02. 03. 04. 05.

<?php require_once(dirname(__FILE__) . '/lib/Doctrine.php'); spl_autoload_register(array('Doctrine', 'autoload')); $conn = Doctrine_Manager::connection('mysql://root:password@localhost /ontuts_doctrine', 'doctrine'); Doctrine_Core::generateModelsFromDb('models', array('doctrine'), array('generateTableClasses'

Nos aseguramos de que existe la carpeta models en la raz de nuestro proyecto:

6 de 16

13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts

http://web.ontuts.com/tutoriales/utilizando-doctri...

view plain

copy to clipboard

print

01.

mkdir

/path/myproject/models

Ahora llamamos al script, bien va Apache o va CLI:


01. php5 -f create_orm_model.php

Una vez se ha ejecutado con xito, vamos a la carpeta models y vemos que se han generado varios cheros: Users.php UsersTable.php UserComments.php UserCommentsTable.php generated/BaseUsers.php generated/BaseUsersComments.php Si te jas, se han creado las clases que se extienden de Doctrine_Record y Doctrine_Table que ya hemos comentado antes. BaseUsers.php y BaseUsersComments.php representan clases base y que no deberas modicar. Cualquier mtodo o propiedad que desees aadir, debes hacerlo sobre Users.php o UsersComments.php. Paso 3: extender el modelo Analizando la aplicacin llegamos a la conclusin de que la clase Users necesita dos nuevos mtodos: getName: que devuelva el nombre del usuario o Desconocido si no ha rellenado esa informacin. addComment: que inserte un nuevo comentario asignado a dicho usuario. Editamos entonces el chero Users.php y lo dejamos as:
view plain copy to clipboard print ?

01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11.

<?php class Users extends BaseUsers { public function addComment($text){ $comment = new UsersComments(); $comment->id_user = $this->id; $comment->text = $text; $comment->save(); } public function getName(){ if(emptyempty($this->name) || is_null($this->name)){

7 de 16

13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts


12. 13. 14. 15. 16. 17. return "Desconocido"; }else{ return $this->name; } } }

http://web.ontuts.com/tutoriales/utilizando-doctri...

Tambien necesitamos extender la clase UsersCommentsTable para sobreescribir el mtodo ndAll(), de forma que obtenga la informacin cruzada con la tabla users y as mejorar el rendimiento. Editamos el chero UsersCommentsTable.php y lo dejamos as:
view plain copy to clipboard print ?

01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.

<?php class UsersCommentsTable extends Doctrine_Table { /** * Returns an instance of this class. * * @return object UsersCommentsTable */ public static function getInstance() { return Doctrine_Core::getTable('UsersComments'); } public function findAll($hydrationMode = null){ $q = Doctrine_Query::create() ->select('c.*,u.name') ->from('UsersComments c') ->innerJoin('c.Users u'); return $q->execute(); } }

Listo, ya tenemos nuestro modelo ampliado Paso 4: crear la lgica

A continuacin creamos el chero index.php que contendr la lgica principal de la aplicacin. Nos queda algo as: index.php
view plain copy to clipboard print ?

01. 02. 03. 04. 05. 06. 07. 08. 09. 10.

<?php //Carga Doctrine require_once(dirname(__FILE__) . '/lib/Doctrine.php'); spl_autoload_register(array('Doctrine', 'autoload')); $conn = Doctrine_Manager::connection('mysql://root@localhost /ontuts_doctrine', 'doctrine'); $conn->setCharset('utf8'); Doctrine_Core::loadModels('models'); //Variable en la plantilla html $tpl = array("comments"=> array(), "error"=>false);

8 de 16

13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts


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.

http://web.ontuts.com/tutoriales/utilizando-doctri...

//Comprueba si se ha enviado el formulario if(!emptyempty($_POST) && isset($_POST['create_comment'])){ $email = filter_input(INPUT_POST, "email", FILTER_SANITIZE_STRING); $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING); $text = filter_input(INPUT_POST, "text", FILTER_SANITIZE_STRING); //Comprueba que se hayan rellenado los campos obligatorios if(!emptyempty($email) && !is_null($email) && !emptyempty($text) && !is_null($text)){ $userTable = Doctrine_Core::getTable('Users'); $users = $userTable->findByEmail($email); $user = null; //Si el usuario no existe, lo crea if($users->count()==0){ $user = new Users(); $user->name = $name; $user->email = $email; $user->save(); }else{ $user = $users[0]; } //Inserta el comentario $user->addComment($text); }else{ //Si no se se han rellenado todos los valores obligatorios //mostrar un error $tpl['error'] = true; } } //Carga los comentarios $commentsTable = Doctrine_Core::getTable('UsersComments'); $tpl['comments'] = $commentsTable->findAll(); //Envia la informacin require_once('template.phtml');

Paso 5: crear la plantilla Por ltimo ya solo nos queda dar formato visual al contenido de template.phtml:
view plain copy to clipboard print ?

01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14.

<!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" lang="en" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <h2>Aadir comentario</h2> <?if($tpl['error']):?> <p>Por favor, rellena las cajas marcadas con asterisco (*)</p><?endif?> <form action="index.php" method="post"> <label>Direccin e-mail *</label><br/> <input type="text" name="email"/><br/> <label>Nombre</label><br/> <input type="text" name="name"/><br/> <label>Comentario *</label><br/>

9 de 16

13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts


15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25.

http://web.ontuts.com/tutoriales/utilizando-doctri...

<textarea name="text" cols="80" rows="5"></textarea><br/> <input type="submit" name="create_comment" value="Enviar"/> </form> <h2>Comentarios de los usuarios</h2> <ul> <?foreach($tpl['comments'] as $comment):?> <li><a href="mailto:<?=$comment->Users->email?>"> <?=$comment->Users->getName()?></a> - <?=$comment->text?></li> <?endforeach?> </ul> </body> </html>

Reexin nal
Como has visto, en cuestin de minutos tenemos una mini aplicacin en PHP que nos permite aadir y listar registros de una base de datos de una forma muy ordenada y sin tocar ni una letra de cdigo SQL. No llevara mucho tiempo aadir un sistema de login de usuarios y que pudiesen editar y borrar los comentarios, gracias a los mtodos save() y delete() de la clase Doctrine_Record. Nos vemos en la prxima publicacin!

Te sugerimos otras entradas relacionadas...

Cmo validar un formulario utilizando PHP y Javascript (jQuery)

10 de 16

13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts

http://web.ontuts.com/tutoriales/utilizando-doctri...

Creando una capa de conexin abstracta a base de datos con PHP

Introduccin a Object-Relational Mapping (ORM)

Acelerando los tiempos de carga uniendo archivos Javascript con PHP

Necesitas desarrollar un proyecto web o para mviles? Estamos disponibles!

Cokidoo, los creadores de Ontuts, desarrollamos proyectos tecnolgicos centrados en redes sociales y aplicaciones web, aplicaciones mviles y consultora web y bases de datos.

11 de 16

13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts

http://web.ontuts.com/tutoriales/utilizando-doctri...

Somos jvenes, inquietos, verstiles, apasionados por la innovacin y enfocados en las nuevas tecnologas. Con Ontuts tratamos de compartir nuestro conocimiento adquirido en los distintos proyectos, ayudando a la comunidad y mostrando nuestra capacidad tecnolgica. Si necesitas un presupuesto sin compromiso, estamos disponibles, no dudes en contactar con nosotros.

Comentarios en esta publicacin (7 comentarios)


Te ha gustado esta publicacin? Puedes compartir tu opinin con todos nosotros! Simplemente pincha aqu mismo. marcos Hola muy interesante tu Post!! me sirve mucho est ateoria y algo de practica pues estoy entrando al mundo de symfony y esto me valdra mucho! gracias por postear este tutorial atte marcos velasquez Publicado el da 10 de noviembre del ao 2010 Alberto Es para la versin 1 o 2 de Doctrine? Publicado el da 01 de febrero del ao 2011 Jorge Leguia Muy bueno tu post. Est bien elaborado y es objetivo. Gracias y Ojal cuelgues una Aplicacin practica igual utilizando Symfony o Zend. Este ejemplo lo probe con Doctrine 1.2 y me funcion. En cuanto al Doctrine 2.0, solo trabaja con PHP 5.3.+ y estos ejemplos no funcionan ya que la estructura de archivos es otra, etc. Saludos

12 de 16

13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts

http://web.ontuts.com/tutoriales/utilizando-doctri...

Publicado el da 07 de marzo del ao 2011

Rafael Excelente trabajo, estoy empezando con CodeIgniter y este material es muy valioso. Gracias Saludos Publicado el da 05 de abril del ao 2011 madeley hola quiero hacer una consulta donde trabajo hay un sistema que se va a eliminar para crear uno nuevo me estan pidiendo que use doctrine no conozco de esa herramienta asi que tengo que estudiar quiero saber si se puede trabajar con doctrine sin utilizar framework como symfony por ejemplo osea doctrine solo y como se trabajaria? con que herramienta puedo codicar que sea amigable y que acepte doctrine por ejemplo algo como eclipse me han hablado de netbean pero no c mucho de el me puedes ayudar Publicado el da 16 de junio del ao 2011 javier es caca Publicado el da 27 de julio del ao 2011

Lucas Te agradezco por la info, siempre viene muy bien algo de teora bien explicada. Uso symfony desde hace 6 meses y cada da me convence ms. Gracias! Publicado el da 25 de agosto del ao 2011 Aade Tu Comentario
E s

13 de 16

13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts

http://web.ontuts.com/tutoriales/utilizando-doctri...

Nombre Email URL (Opcional) Aadir Comentario Avsame si hay nuevos comentarios via e-mail Buscar en Ontuts...

Conoce a los creadores...

Desde la empresa Cokidoo tratamos de ayudar a desarrolladores y diseadores web compartiendo nuestro conocimiento. Suscritos al Feed RSS Followers en Twitter 442 Fans en Facebook Suscrbete via E-mail ahora! cracks.ontuts: slo los mejores Anunciarse en Ontuts Ayudamos a promocionar productos y servicios a empresas y freelancers.

Advertise Here Advertise Here

nete a la Comunidad ickr

14 de 16

13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts

http://web.ontuts.com/tutoriales/utilizando-doctri...

Se ha escrito sobre...
anlisis apis arte base datos

concursos

consejos

css diseo ecommerce entrevista

fuentes google gratis herramientas html html5 iconos imgenes indie

Inspiracin

javascript jquery juno logos maquetacion microsoft noticias novedades opinin optimizacin php
internet explorer

programacin
themes

python

Recursos web silverlight sorteos

sprites

tipograa tutorial videojuegos web wordpress xbox

15 de 16

13-12-2013 11:23

Utilizando Doctrine como ORM en PHP | Web.Ontuts

http://web.ontuts.com/tutoriales/utilizando-doctri...

Ontuts.com, tutoriales, diseo, inspiracion & recursos web - Entradas (RSS) and Comentarios (RSS). Algunos iconos de WeFunction.

16 de 16

13-12-2013 11:23