idesweb-prac13-PHPpdoadodb

13
Introducción al desarrollo web (iDESWEB) - 3 a ed. Práctica 13: PHP 6 (acceso a una base de datos con PDO y ADOdb) 1. Objetivos Aprender a acceder a una base de datos desde PHP con PDO. Aprender a acceder a una base de datos desde PHP con ADOdb. 2. Recursos ¿Qué es PDO? PDO - Objetos de datos de PHP 1 : capa abstracta de acceso a datos de PHP 5. Why you Should be using PHP’s PDO for Database Access 2 : tutorial sobre PDO. Introduction to PHP PDO 3 : tutorial sobre PDO. ¿Qué es ADOdb? ADOdb Database Abstraction Library for PHP (and Python) 4 : página oficial del proyecto ADOdb. ADOdb Manual 5 : manual de la librería ADOdb. Existe una traducción al español 6 , pero no está actualizada. Tutorial: Moving from MySQL to ADODB 7 : tutorial que explica cómo pasar de usar las fun- ciones nativas de MySQL a emplear el acceso mediante ADOdb. Existe una traducción al español 8 , pero no está actualizada. ¿Implica alguna pérdida de rendimiento emplear PDO, ADOdb o alguna otra capa intermedia en el acceso a una base de datos? PHP Database Functions vs. PEAR::DB vs. ADOdb (and PDO) 9 : compara el tiempo necesario para realizar una consulta SQL sencilla mediante tres métodos (funciones nativas de la base de datos, PEAR::DB y ADOdb). 3. ¿Qué tengo que hacer? En esta práctica se van a desarrollar las funciones que faltan para que la aplicación esté completa y operativa. Una parte se va a implementar con PDO y otra parte con ADOdb. Mediante PDO tienes que implementar las siguientes nuevas opciones: Página detalle usuario Muestra los datos de registro del usuario y un listado de todos sus álbumes. Si se selecciona un álbum, se muestra un listado de la fotos que contiene mediante [Página “Ver álbum”]. 1 http://www.php.net/manual/es/book.pdo.php 2 http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/ 3 http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html 4 http://adodb.sourceforge.net/ 5 http://phplens.com/lens/adodb/docs-adodb.htm 6 http://www.lacorona.com.mx/fortiz/adodb/docs-adodb-es.htm 7 http://phplens.com/lens/adodb/tute.htm 8 http://www.lacorona.com.mx/fortiz/adodb/tute-es.htm 9 http://joseph.randomnetworks.com/archives/2006/04/04/php-database-functions-vs-peardb-vs-adodb/ 1

Transcript of idesweb-prac13-PHPpdoadodb

  • Introduccin al desarrollo web (iDESWEB) - 3a ed.

    Prctica 13: PHP 6 (acceso a una base de datos con PDO y ADOdb)

    1. ObjetivosAprender a acceder a una base de datos desde PHP con PDO.

    Aprender a acceder a una base de datos desde PHP con ADOdb.

    2. RecursosQu es PDO?

    PDO - Objetos de datos de PHP1: capa abstracta de acceso a datos de PHP 5.

    Why you Should be using PHPs PDO for Database Access2: tutorial sobre PDO.

    Introduction to PHP PDO3: tutorial sobre PDO.

    Qu es ADOdb?

    ADOdb Database Abstraction Library for PHP (and Python)4: pgina oficial del proyectoADOdb.

    ADOdb Manual5: manual de la librera ADOdb. Existe una traduccin al espaol6, pero no estactualizada.

    Tutorial: Moving from MySQL to ADODB7: tutorial que explica cmo pasar de usar las fun-ciones nativas de MySQL a emplear el acceso mediante ADOdb. Existe una traduccin al espaol8,pero no est actualizada.

    Implica alguna prdida de rendimiento emplear PDO, ADOdb o alguna otra capa intermedia en elacceso a una base de datos?

    PHP Database Functions vs. PEAR::DB vs. ADOdb (and PDO)9: compara el tiemponecesario para realizar una consulta SQL sencilla mediante tres mtodos (funciones nativas de labase de datos, PEAR::DB y ADOdb).

    3. Qu tengo que hacer?En esta prctica se van a desarrollar las funciones que faltan para que la aplicacin est completa y

    operativa. Una parte se va a implementar con PDO y otra parte con ADOdb.Mediante PDO tienes que implementar las siguientes nuevas opciones:

    Pgina detalle usuario Muestra los datos de registro del usuario y un listado de todos sus lbumes.Si se selecciona un lbum, se muestra un listado de la fotos que contiene mediante [Pgina Verlbum].

    1http://www.php.net/manual/es/book.pdo.php2http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/3http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html4http://adodb.sourceforge.net/5http://phplens.com/lens/adodb/docs-adodb.htm6http://www.lacorona.com.mx/fortiz/adodb/docs-adodb-es.htm7http://phplens.com/lens/adodb/tute.htm8http://www.lacorona.com.mx/fortiz/adodb/tute-es.htm9http://joseph.randomnetworks.com/archives/2006/04/04/php-database-functions-vs-peardb-vs-adodb/

    1

  • Figura 1: Diagrama de pginas que componen el sitio web

    Respuesta Eliminar foto Desde la [Pgina Ver lbum] del men de usuario registrado, eliminauna foto de un lbum (solicitar confirmacin). Opcional: permitir que el usuario pueda eliminarmltiples fotos de una sola vez.

    Pgina Ver lbum Desde la [Pgina detalle foto] y la [Pgina detalle usuario], muestra todas lasfotos que contiene el lbum seleccionado.

    Respuesta Eliminar lbum Desde la [Pgina Mis lbumes] del men de usuario registrado, eliminaun lbum y todas las fotos que contiene (solicitar confirmacin).

    En concreto, tienes que modificar o crear las pginas que se indican con un color de relleno oscuro enla Figura 1.

    Adems, mediante ADOdb tienes que implementar un sistema de comentarios para las fotos. Estesistema slo est disponible para los usuarios registrados. Un usuario puede publicar uno o varios comen-tarios en cualquier foto. Un comentario se compone de un texto y una fecha (automtica). Los comentariosse visualizan cuando se consultan los detalles de una foto. Para desarrollar esta nueva funcin tendrsque modificar la estructura de la base de datos para que se puedan almacenar los comentarios.

    Opcional: puedes hacer que los comentarios sean moderados, y no se publiquen hasta que el propietariode la foto los revise y los acepte.

    2

  • Figura 2: Diagrama de capas de acceso a una base de datos

    4. Cmo lo hago?Tanto PDO con ADOdb son capas abstractas de acceso a sistemas gestores de bases de datos. Como

    se puede ver en la Figura 2, la capa abstracta se sita entre la aplicacin y el controlador especfico deacceso a una base de datos.

    El uso de una capa abstracta tiene dos problemas:

    1. Una capa abstracta aade una capa ms de procesamiento, lo que implica una prdida de velocidadde procesamiento.

    2. Algunas caractersticas especficas de un sistema gestor de bases de datos pueden no estar disponiblesa travs de la capa abstracta.

    En la mayora de las situaciones, ambos problemas pueden ser ignorados, pero hay que recordar queexisten estos problemas.

    4.1. Uso de PDOPDO (PHP Data Objects) proporciona una capa abstracta de acceso a bases de datos: independien-

    temente de la base de datos que se est utilizando, PDO permite usar las mismas funciones para realizarconsultas y obtener datos. Sin embargo, PDO no proporciona una abstraccin de las bases de datos, noreescribe las sentencias SQL y no emula caractersticas ausentes en la base de datos.

    PDO est disponible de forma nativa desde PHP 5.1, y tambin se puede usar en PHP 5.0 como unaextensin PECL. PDO requiere las caractersticas nuevas de orientacin a objetos de PHP 5, por lo queno se puede ejecutar con versiones anteriores de PHP.

    En la actualidad se han implementado los siguientes controladores PDO10: Cubrid, FreeTDS / Mi-crosoft SQL Server / Sybase, Firebird/Interbase 6, IBM DB2, IBM Informix Dynamic Server, MySQL3.x/4.x/5.x, Oracle Call Interface, ODBC v3 (IBM DB2, unixODBC and win32 ODBC), PostgreSQL,SQLite 2/3, Microsoft SQL Server / SQL Azure y 4D.

    Para averiguar qu controladores estn disponibles en un sistema se puede emplear el mtodo esttico11getAvailableDrivers() de la clase PDO:

    print_r(PDO::getAvailableDrivers());

    4.1.1. Clases

    La interfaz de PDO proporciona tres clases:10http://www.php.net/manual/es/pdo.drivers.php11Recuerda que un mtodo esttico se puede ejecutar directamente a travs de la clase, sin crear un objeto.

    3

  • PDO: se encarga de gestionar las conexiones entre PHP y un servidor de bases de datos. Proporcionamtodos para gestionar las transacciones, obtener informacin sobre la conexin a la base de datosy preparar y ejecutar sentencias.

    PDOStatement: representa una sentencia preparada y el resultado asociado a una consulta. Propor-ciona mtodos para asignar valores a una sentencia preparada, para obtener informacin sobre unresultado (nmero de columnas, nmero de filas) y para recorrer un resultado.

    PDOException: representa una excepcin, un error generado por PDO. Proporciona mtodos paraobtener informacin sobre el error producido.

    Las conexiones se establecen creando instancias de la clase PDO. El constructor de esta clase aceptaparmetros para especificar el origen de datos (conocido como DSN, Data Source Name) y, opcionalmente,el nombre de usuario, la contrasea y opciones para el controlador. Los mtodos ms importantes de estaclase son:

    exec(sentencia): ejecuta una sentencia SQL que no devuelva un resultado (por ejemplo, INSERT,UPDATE o DELETE) y devuelve el nmero de filas afectadas.

    lastInsertId(): devuelve el ID autonumrico de la ltima fila insertada.

    prepare(sentencia): crea y devuelve una sentencia preparada para su posterior ejecucin.

    query(sentencia): ejecuta una sentencia SQL y devuelve el resultado como un objeto de tipoPDOStatement.

    La clase PDOStatement posee los siguientes mtodos principales:

    bindParam(parametro, variable): vincula una variable a un parmetro en una sentencia prepa-rada.

    bindValue(parametro, valor): vincula un valor a un parmetro en una sentencia preparada.

    columnCount(): devuelve el nmero de columnas de un resultado.

    execute(): ejecuta una sentencia preparada.

    fetch(estilo): devuelve la siguiente fila en un resultado. La forma de devolver la fila se controlacon el parmetro estilo que puede tomar los valores:

    PDO::FETCH_ASSOC: devuelve un array indexado por los nombres de las columnas del resultado. PDO::FETCH_BOTH (predeterminado): devuelve un array indexado tanto por los nombres de las

    columnas como por las posiciones de las columnas en el resultado comenzando por la columna0.

    PDO::FETCH_NUM: devuelve un array indexado por las posiciones de las columnas en el resultadocomenzando por la columna 0.

    PDO::FETCH_OBJ: devuelve un objeto annimo con nombres de propiedades que se correspon-den a los nombres de las columnas del resultado.

    fetchAll(estilo): devuelve un array que contiene todas las filas de un resultado. La forma dedevolver las filas se controla con el parmetro estilo que puede tomar los mismos valores que elmtodo fetch(estilo).

    fetchObject(): devuelve la siguiente fila de un resultado en forma de objeto.

    rowCount(): devuelve el nmero de filas afectadas por la ltima sentencia SQL.

    La clase PDOException posee los siguientes mtodos principales:

    getFile(): devuelve la ruta y el nombre del fichero en el que se ha producido la excepcin.

    getLine(): devuelve el nmero de la lnea de cdigo en la que se ha producido la excepcin.

    getCode(): devuelve el cdigo de la excepcin.

    4

  • getMessage(): devuelve el mensaje de la excepcin.

    Por defecto, la generacin de excepciones est desactivada y no se producen excepciones (sin embargo,cuando se produce un error en la conexin, siempre se produce una excepcin). Para activar la generacinde excepciones se debe emplear el mtodo setAttribute para modificar el atributo de configuracin deerrores PDO::ATTR_ERRMODE con el valor PDO::ERRMODE_EXCEPTION:

    PDO::ERRMODE_SILENT: el valor por defecto, no se generan excepciones (excepto para un error deconexin).

    PDO::ERRMODE_WARNING: los errores generan una advertencia de PHP y contina la ejecucin (tilpara depurar un cdigo).

    PDO::ERRMODE_EXCEPTION: se genera una excepcin cuando se produce un error.

    4.1.2. Acceso a una base de datos

    El siguiente ejemplo muestra como realizar un acceso bsico a una base de datos mediante PDO; paracrear una conexin con la base de datos se emplea la clase PDO; en este ejemplo se emplea fetchAll()para obtener todo el resultado en forma de array bidimensional que se imprime directamente con lafuncin print_r():

    Prueba bsica con PDO

    La clase PDOStatement implementa la interfaz Traversable, lo que significa que puede ser recorridamediante un bucle foreach(). El ejemplo anterior se puede escribir tambin como:

    5

  • Prueba bsica con PDO

    4.1.3. Mapeo a objetos

    Una caracterstica muy importante de PDO es que permite un mapeo automtico de los resultadosde una consulta en objetos. Este mecanismo facilita mucho la programacin, simplifica el cdigo y reducelas posibilidades de error. Por ejemplo, en el siguiente cdigo se recupera una fila de la base de datos conel mtodo fetchObject() que se convierte automticamente a un objeto de la clase Libro que posee elmtodo mostrar() que devuelve el objeto formateado como una lista HTML:

    Prueba bsica con PDO

  • private $isbn;

    public function mostrar() {return editorial}ISBN: {$this->isbn}

    hereDOC;

    }}

    try {$con = new PDO(mysql:host=localhost;dbname=biblioteca, wwwdata, );$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Ejecuta una sentencia SQL$sentencia = SELECT * FROM libros WHERE id = 3;$resultado = $con->query($sentencia);$libro = $resultado->fetchObject("Libro");echo $libro->mostrar();

    // Para liberar un resultado simplemente hay que destruir el objeto$resultado = NULL; // Opcional// Para cerrar una conexin simplemente hay que destruir el objeto$con = NULL; // Opcional

    } catch(PDOException $e) {echo "Error!";echo "Fichero: " . $e->getFile() . "";echo "Lnea: " . $e->getLine() . "";echo "Cdigo: " . $e->getCode() . "";echo "Mensaje: " . $e->getMessage() . "";

    }?>

    4.1.4. Sentencias preparadas

    Una sentencia preparada o una sentencia parametrizada se usa para ejecutar la misma sentenciarepetidamente con gran eficiencia. La ejecucin de una sentencia preparada consta de dos partes:

    La preparacin: se define una plantilla con marcadores (parmetros) que se enva al servidor paraque realice una comprobacin de su sintaxis e inicialice los recursos necesarios para su posteriorejecucin.

    La ejecucin: se vinculan los valores a los parmetros de la sentencia y se enva al servidor para suejecucin.

    PDO permite dos formatos de marcadores de parmetros en las sentencias preparadas: marcadorescon nombre (:nombre) y marcadores de posicin annimos (?). Los marcadores se pueden sustituir porsu valor de diferentes formas: se pueden sustituir al ejecutar la sentencia preparada con execute(),que puede recibir un array con los valores de sustitucin, o se pueden usar los mtodos bindParam() obindValue() para realizar la sustitucin.

    El siguiente ejemplo muestra cmo se utilizan las sentencias preparadas con marcadores con nombre:

  • "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

    Prueba bsica con PDO

    El uso de las sentencias preparadas ofrece dos ventajas muy importantes:

    1. Ofrece un aumento de velocidad en la ejecucin de una sentencia cuando se ejecuta varias veces: lasentencia no se tiene que analizar e interpretar cada vez, sino que est lista para ejecutarse tantasveces como se quiera.

    2. Ofrece proteccin frente a la inyeccin SQL.

    PDO proporciona soporte para sentencias preparadas aunque el sistema gestor de bases de datos nolas soporte (en este caso, no se observar un aumento en la velocidad de ejecucin).

    4.1.5. Transacciones

    Una transaccin es un conjunto de operaciones que se ejecutan como si fueran una sola. En unatransaccin, la ejecucin de las operaciones no puede finalizar en un estado intermedio: si por algunarazn, se tiene que cancelar la transaccin, el sistema gestor de bases de datos anula las operacionesejecutadas hasta ese momento para dejar la base de datos en su estado inicial.

    En PDO, los mtodos que se emplean para manejar las transacciones son:

    beginTransaction(): inicia una transaccin y desactiva el modo autocommit.

    commit(): finaliza una transaccin con xito y vuelve al modo autocommit.

    8

  • Figura 3: Estructura de la tabla cuenta

    Figura 4: Estado inicial de las cuentas bancarias

    rollBack(): anula una transaccin (cancela las operaciones realizadas) y vuelve al modo auto-commit.

    Un ejemplo tpico de transaccin es el traspaso de una cantidad de dinero entre dos cuentas bancarias.En la Figura 3 se muestra la estructura de la tabla cuenta que posee cuatro campos: numero (nmerode cuenta), titular (nombre del titular), saldo (saldo de la cuenta con dos decimales de precisin) yfecha (fecha de la ltima operacin).

    En la Figura 4 se muestra el estado inicial de las cuentas bancarias: existen tres cuentas, las tres conun saldo de 100 unidades y la fecha vaca (0000-00-00 00:00:00).

    El siguiente cdigo ejecuta dos operaciones con las cuentas: un traspaso de 40 unidades de la cuenta123 a la cuenta 456 y un traspaso de 50 unidades de la cuenta 123 a la cuenta 789. Las dos operacionesse pueden realizar si la cuenta 123 no se queda con un saldo negativo. Para asegurar que se cumple esterequisito se utiliza una transaccin: si despus de realizar las dos operaciones, el saldo de la cuenta esmayor o igual que cero, se confirma la transaccin; si el saldo es menor que cero, se anula la transaccin.

    Prueba bsica con PDO

  • Figura 5: Estado de las cuentas bancarias despus de realizar la operacin

    $con->commit();echo "Transaccin realizada";

    }else {

    $con->rollBack();echo "Transaccin anulada";

    }

    // Para cerrar una conexin simplemente hay que destruir el objeto$con = NULL; // Opcional

    } catch(PDOException $e) {echo "Error!\n";echo "Fichero: " . $e->getFile() . "";echo "Lnea: " . $e->getLine() . "";echo "Cdigo: " . $e->getCode() . "";echo "Mensaje: " . $e->getMessage() . "";

    }?>

    La primera vez que se ejecuta el cdigo anterior, el estado de las cuentas pasa a ser el que se muestraen la Figura 5. Si se vuelve a ejecutar el cdigo, como la cuenta 123 se quedara con un saldo negativo,la transaccin se anula y no se produce ningn cambio en el estado de las cuentas bancarias.

    4.2. Uso de ADOdbADOdb es una librera de clases para acceder a bases de datos para PHP que posee un funcionamiento

    similar a Microsoft ADO. ADOdb ofrece un acceso estndar a diversos SGBD, ya que oculta (encapsula)las diferencias. En la actualidad, ADOdb ofrece acceso a MySQL, Oracle, Microsoft SQL Server, Sybase,Sybase SQL Anywhere, Informix, PostgreSQL, FrontBase, SQLite, Interbase (Firebird y las variantes deBorland), Microsoft Foxpro, Microsoft Access, ADO, IBM DB2, SAP DB y ODBC.

    Las clases principales que se emplean en ADOdb son ADOConnection y ADORecordSet. La claseADOConnection posee las siguientes propiedades y mtodos principales:

    Close(): cierra la conexin y libera toda la memoria y recursos ocupados.

    Connect(servidor, usuario, contrasea, baseDatos): abre una conexin con una base de da-tos.

    ErrorMsg(): devuelve una descripcin del ltimo error.

    ErrorNo(): devuelve el cdigo del ltimo error o 0 si no ha habido error.

    Execute(sentencia): ejecuta una sentencia SQL y devuelve un objeto ADORecordSet.

    La clase ADORecordSet posee las siguientes propiedades y mtodos principales:

    Close(): cierra el resultado y libera toda la memoria y recursos ocupados.

    EOF: devuelve true si el cursor interno ha superado la ltima fila del resultado y false en casocontrario.

    10

  • FieldCount(): devuelve el nmero de campos (columnas) en un resultado.

    fields: array que contiene la fila actual.

    GetRows(): devuelve todas las filas del resultado en forma de array bidimensional.

    MoveFirst(): mueve el cursor interno a la primera fila en el resultado.

    MoveNext(): mueve el cursor interno a la ltima fila en el resultado.

    RecordCount(): devuelve el nmero de filas en un resultado.

    Para usar ADOdb en PHP es necesario incluir en el cdigo el fichero adodb.inc.php en cada pginadonde se vaya a utilizar. Si emplea la directiva include_path del fichero php.ini, se puede evitar eltener que copiar los ficheros de ADOdb en cada sitio web o emplear rutas de acceso complicadas. La di-rectiva include_path permite definir una lista de directorios donde las funciones require(), include(),fopen(), file(), readfile() y file_get_contents() buscarn los ficheros.

    Por ejemplo, en XAMPP la directiva include_path est configurada como .;C:\xampp\php\pear\.El siguiente ejemplo muestra como realizar un acceso bsico a una base de datos mediante ADOdb;

    para crear una conexin con la base de datos se puede emplear tanto NewADOConnection(driver) comoADONewConnection(driver), ya que ambos son sinnimos; en este ejemplo se ha activado la propiedaddebug para mostrar informacin de depuracin (como por ejemplo, la sentencia SQL que se ejecuta) yse emplea GetRows() para obtener todo el resultado en forma de array bidimensional que se imprimedirectamente con la funcin print_r():

    Prueba bsica con ADOdb

    El siguiente ejemplo, un poco ms elaborado, muestra en forma de tabla HTML el resultado de ejecutaruna sentencia SQL; para ello recorre fila a fila y columna a columna el resultado:

    11

  • Prueba de SELECT con ADOdb

    5. RecomendacionesExisten distintas formas de acceder a una base de datos desde PHP, todas ellas con sus ventajas y

    desventajas. Intenta conocerlas todas y utiliza la que ms te guste.PHP ofrece tres APIs diferentes para conectarse a MySQL12. En la Figura 6 se muestra una compa-

    rativa de mysqli, PDO_MySQL y mysql Se recomienda usar las extensiones mysqli o PDO_MySQL. Nose recomienda usar la antigua extensin mysql para nuevos desarrollos, ya que se considera obsoleta y nose desarrollan nuevas funcionalidades para ella, slo se mantiene.

    Recuerda que el acceso nativo (mediante las funciones especficas que proporciona PHP) es el mtodo12http://www.php.net/manual/es/mysqlinfo.api.choosing.php

    12

  • Figura 6: Comparativa mysqli, PDO_MySQL y mysql

    ms rpido y el que ofrece el acceso a todas las funcionalidades del SGBD. Cuando se utiliza una capaintermedia, como PDO, ADOdb u ODBC, el acceso es ms lento y ciertas caractersticas quizs no estndisponibles.

    13