Introducción
La extensión Objetos de Datos de PHP (PDO por
sus siglas en inglés) define una interfaz ligera para poder acceder a bases de
datos en PHP. Cada controlador de bases de datos que implemente la interfaz PDO
puede exponer características específicas de la base de datos, como las
funciones habituales de la extensión. Obsérvese que no se puede realizar
ninguna de las funciones de la bases de datos utilizando la extensión PDO por
sí misma; se debe utilizar un controlador de PDO específico de la base de datos
para tener acceso a un servidor de bases de datos.
PDO proporciona una capa de abstracción de acceso
a datos, lo que significa que, independientemente de la base de datos que
se esté utilizando, se usan las mismas funciones para realizar consultas y
obtener datos. PDO no proporciona una abstracción de bases de datos;
no reescribe SQL ni emula características ausentes. Se debería usar una capa de
abstracción totalmente desarrollada si fuera necesaria tal capacidad.
Instalación:
Usuarios de Windows
- PDO
y la mayoría de controladores vienen en PHP como extensiones compartidas,
para activarlas, solo se debe editar el fichero php.ini
extension=php_pdo.dll
Después, elija los demás ficheros DLL de bases de datos específicas, y utilice dl() para cargarlos en tiempo de ejecución, o actívelos en php.ini por debajo de la línea php_pdo.dll. Por ejemplo:
Estas DLLs deberían existir en el directorio del
sistema extension_dir.
|
Nota:
Después
de realizar cambios en el fichero php.ini,
será necesario reiniciar
PHP para que las nuevas directivas de configuración logren su efecto.
extension=php_pdo.dll
extension=php_pdo_firebird.dll
extension=php_pdo_informix.dll
extension=php_pdo_mssql.dll
extension=php_pdo_mysql.dll
extension=php_pdo_oci.dll
extension=php_pdo_oci8.dll
extension=php_pdo_odbc.dll
extension=php_pdo_pgsql.dll
extension=php_pdo_sqlite.dll
|
Constantes predefinidas
|
Nota:
PDO utiliza constantes de clase desde PHP 5.1. Las versiones anteriores usan constantes globales bajo la forma PDO_PARAM_BOOL. |
PDO::PARAM_BOOL (integer)
Representa un tipo de dato
booleano.
PDO::PARAM_NULL (integer)
Representa el tipo de dato NULL
de SQL.
PDO::PARAM_INT (integer)
Representa el tipo de dato
INTEGER de SQL.
PDO::PARAM_STR (integer)
Representa el tipo de dato CHAR,
VARCHAR de SQL, u otro tipo de datos de string.
PDO::PARAM_LOB (integer)
Representa el tipo de dato LOB
(objeto grande) de SQL.
PDO::PARAM_STMT (integer)
Representa un tipo de conjunto de
registros. No está admitido actualmente por ningún controlador.
PDO::PARAM_INPUT_OUTPUT (integer)
Especifica que el parámetro es de
entrada/salida (INOUT) para un procedimiento almacenado. Se debe realizar un OR
a nivel de bits con un tipo de datos PDO::PARAM_* explícito.
PDO::FETCH_LAZY (integer)
Especifica que el método de
obtención debe devolver cada fila como un objeto con los nombres de las
variables que se corresponden a los nombres de las columnas devueltos en el
conjunto de resultados. PDO::FETCH_LAZY crea los nombres de las
variables del objeto a medida que se acceden a ellas. No es válida dentro
de PDOStatement::fetchAll().
PDO::FETCH_ASSOC (integer)
Especifica que el método de
obtención debe devolver cada fila como un array indexado por los nombres de las
columnas devueltos en el correspondiente conjunto de resultados. Si éste
contiene múltiples columnas con el mismo nombre, PDO::FETCH_ASSOC devuelve un único valor por
nombre de columna.
PDO::FETCH_NAMED (integer)
Especifica que el método de
obtención debe devolver cada fila como un array indexado por los nombres de las
columnas devueltos en el correspondiente conjunto de resultados. Si éste
contiene múltiples columnas con el mismo nombre, PDO::FETCH_NAMED devuelve un array de
valores por nombre de columna.
PDO::FETCH_NUM (integer)
Especifica que el método de
obtención debe devolver cada fila como un array indexado por los números de
columna devueltos en el correspondiente conjunto de resultados, comenzando por
la columna 0.
PDO::FETCH_BOTH (integer)
Especifica que el método de
obtención debe devolver cada fila como un array indexado tanto por los nombres
como por los números de las columnas devueltos en el correspondiente conjunto
de resultados, comenzando por la columna 0.
PDO::FETCH_OBJ (integer)
Especifica que el método de
obtención debe devolver cada fila como un objeto con los nombres de sus
propiedades correspondientes a los nombres de las columnas devueltos en el
conjunto de resultados.
PDO::FETCH_BOUND (integer)
Especifica que el método de
obtención debe devolver TRUE y asignar los valores de las columnas del conjunto
de resultados a las variables de PHP a las cuales están vinculadas con los
métodosPDOStatement::bindParam() o PDOStatement::bindColumn().
PDO::FETCH_COLUMN (integer)
Especifica que el método de
obtención debe devolver una única columna solicitada de la siguiente fila del
conjunto de resultados.
PDO::FETCH_CLASS (integer)
Especifica que el método de
obtención debe devolver una nueva instancia de la clase solicitada, haciendo corresponder
las columnas con los nombres de las propiedades de la clase.
PDO::FETCH_INTO (integer)
Especifica que el método de
obtencion debe actualizar una instancia existente de la clase solicitada,
haciendo corresponder las columnas con los nombres de las propiedades de la
clase.
PDO::FETCH_FUNC (integer)
Permite personalizar
completamente la forma en que los datos son tratados al vuelo (únicamente
válida dentro de PDOStatement::fetchAll()).
PDO::FETCH_GROUP (integer)
Grupo devuelto según valores.
Usualmente combinada con PDO::FETCH_COLUMN o PDO::FETCH_KEY_PAIR.
PDO::FETCH_UNIQUE (integer)
Obtener solamente los valores
únicos.
PDO::FETCH_KEY_PAIR (integer)
Obtener un resultado de dos
columnas como un array donde la primera columna es la clave y la segunda el
valor.
PDO::FETCH_CLASSTYPE (integer)
Determinar el nombre de la clase
desde el valor de la primera columna.
PDO::FETCH_SERIALIZE (integer)
Igual que PDO::FETCH_INTO salvo que el objeto es
proporcionado como una cadena serializada.
PDO::FETCH_PROPS_LATE (integer)
Llamar al contructor antes de
establecer propiedades.
PDO::ATTR_AUTOCOMMIT (integer)
Si este valor es FALSE, PDO intenta descativar la
autoconsigna de forma que la conexión comience una transacción.
PDO::ATTR_PREFETCH (integer)
Establecer el tamaño de la
precarga permite obtener un equilibrio entre rapidez y uso de memoria para la
aplicación. No todas las combinaciones base de datos/controlador admiten
establecer el tamaño de la precarga. Un valor más grande de precarga da como
resultado un aumento del rendimiento a costa de un mayor uso de memoria.
PDO::ATTR_TIMEOUT (integer)
Establece el valor del tiempo de
espera, en segundos, para las comunicaciones con la base de datos.
PDO::ATTR_ERRMODE (integer)
Véase la sección Errores y
su manejo para obtener más información sobre este atributo.
PDO::ATTR_SERVER_VERSION (integer)
Este es un atributo de sólo
lectura; devolverá información sobre la versión del servidor de bases de datos
al que está conectado PDO.
PDO::ATTR_CLIENT_VERSION (integer)
Este es un atributo de sólo
lectura; devolverá información sobre la versión de las bibliotecas cliente que
el controlador de PDO está usando.
PDO::ATTR_SERVER_INFO (integer)
Este es un atributo de sólo
lectura; devolverá alguna metainformación sobre el servidor de bases de datos
al que está conectado PDO.
PDO::ATTR_CONNECTION_STATUS (integer)
PDO::ATTR_CASE (integer)
Forzar a los nombres de las
columnas al uso de mayúsculas/minúsculas especificado por las constantesPDO::CASE_*.
PDO::ATTR_CURSOR_NAME (integer)
Obtener o establecer el nombre a
usar para un cursor. Es más útil cuando se utilizan cursores desplazables y
actualizacioines posicionadas.
PDO::ATTR_CURSOR (integer)
Selecciona el tipo de cursor. PDO
actualmente admite PDO::CURSOR_FWDONLY y PDO::CURSOR_SCROLL. Cíñase a PDO::CURSOR_FWDONLY a menos que sepa que
necesite un cursor desplazable.
PDO::ATTR_DRIVER_NAME (string)
Devuelve el nombre del
controlador.
PDO::ATTR_ORACLE_NULLS (integer)
Convertir string vacíos a valores
NULL de SQL en la obtención de datos.
PDO::ATTR_PERSISTENT (integer)
Solicitar una conexión
persistente, en vez de crear una nueva conexión. Véase Conexiones y su
administración para obtener más información sobre este atributo.
PDO::ATTR_STATEMENT_CLASS (integer)
PDO::ATTR_FETCH_CATALOG_NAMES (integer)
Anteponer el nombre del catálogo
contenido a cada nombre de columna devuelto en el conjunto de resultados. El
nombre del catálogo y el nombre de columna están separados por el carácter
punto (.). El soporte de este atributo es a nivel del controlador; podría no
estar admitido por el controlador que usted utilice.
PDO::ATTR_FETCH_TABLE_NAMES (integer)
Anteponer el nombre de la tabla
contenida a cada nombre de columna devuelto en el conjunto de resultados. El
nombre de la tabla y el nombre de columna están separados por el carácter punto
(.). El soporte de este atributo es a nivel del controlador; podría no estar
admitido por el controlador que usted utilice.
PDO::ATTR_STRINGIFY_FETCHES (integer)
PDO::ATTR_MAX_COLUMN_LEN (integer)
PDO::ATTR_DEFAULT_FETCH_MODE (integer)
PDO::ATTR_EMULATE_PREPARES (integer)
PDO::ERRMODE_SILENT (integer)
No emitir ningún error o
excepción si ocurrieran. El desarrollador es responsable de comprobar
explícitamente los errores. Este es el modo predeterminado. Véase Errores
y su manejo para obtener más información sobre este atributo.
PDO::ERRMODE_WARNING (integer)
Emitir un mensaje de tipo E_WARNING de PHP si ocurre algún
error. Véase Errores y su manejo para obtener más información sobre
este atributo.
PDO::ERRMODE_EXCEPTION (integer)
Lanzar una excepción de
tipo PDOException si ocurre algún error. Véase Errores y su
manejo para obtener más información sobre este atributo.
PDO::CASE_NATURAL (integer)
Dejar los nombres de las columnas
tal como son devueltas por el controlador de la base de datos.
PDO::CASE_LOWER (integer)
Forzar a los nombres de las
columnas a estar en minúsculas.
PDO::CASE_UPPER (integer)
Fuerza a los nombres de las columnas
a estar en mayúsculas.
PDO::NULL_NATURAL (integer)
PDO::NULL_EMPTY_STRING (integer)
PDO::NULL_TO_STRING (integer)
PDO::FETCH_ORI_NEXT (integer)
Obtener la siguiente fila del
conjunto de resultados. Únicamente válida para cursores desplazables.
PDO::FETCH_ORI_PRIOR (integer)
Obtener la fila anterior del
conjunto de resultados. Únicamente válida para cursores desplazables.
PDO::FETCH_ORI_FIRST (integer)
Obtener la primera fila del
conjunto de resultados. Únicamente válida para cursores desplazables.
PDO::FETCH_ORI_LAST (integer)
Obtener la última fila del
conjunto de resultados. Únicamente válida para cursores desplazables.
PDO::FETCH_ORI_ABS (integer)
Obtener la fila solicitada
mediante el número de fila del conjunto de resultados. Únicamente válida para
cursores desplazables.
PDO::PARAM_EVT_ALLOC (integer)
Evento de asignación
PDO::FETCH_ORI_REL (integer)
Obtener la fila solicitada
mediante la posición relativa de la posición actual del cursor del conjunto de
resultados. Valido para cursores desplazables.
PDO::CURSOR_FWDONLY (integer)
Crear un
objeto PDOStatement con un cursor de sólo avance. Este es la elección
del cursor predeterminada, ya que es el patrón de acceso a datos más rápido y
común en PHP.
PDO::CURSOR_SCROLL (integer)
Crear un
objeto PDOStatement con un cursor desplazable. Pase las
constantes PDO::FETCH_ORI_* para controlar las filas obtenidas
del conjunto de resultados.
PDO::ERR_NONE (string)
Corresponde al SQLSTATE '00000',
el cual significa que la sentencia SQL fue ejecutada con éxito, sin errores ni
advertencias. Esta constante sirve para la comprobación cómoda de PDO::errorCode() oPDOStatement::errorCode()
para determinar si ha ocurrido algún error. En cualquier caso, usualmente se
sabrá si este es el caso examinando el código devuelto por el método que
provocó la condición de error.
PDO::PARAM_EVT_FREE (integer)
Evento de desasigncación
PDO::PARAM_EVT_EXEC_PRE (integer)
Evento provocado antes de la
ejecución de una sentencia preparada.
PDO::PARAM_EVT_EXEC_POST (integer)
Evento provocado después de la
ejecución de una sentencia preparada.
PDO::PARAM_EVT_FETCH_PRE (integer)
Evento provocado antes de la
obtención de un resultado de un conjunto de resultados.
PDO::PARAM_EVT_FETCH_POST (integer)
Evento provocado después de la
obtención de un resultado de un conjunto de resultados.
PDO::PARAM_EVT_NORMALIZE (integer)
Evento provocado durante el registro
de un parámetro vinculado, permitiendo al controlador normalizar el nombre del
parámetro.
Conexiones y su
administración
Las conexiones se establecen creando
instancias de la clase base PDO. No importa el controlador que se utilice;
siempre se usará el nombre de la clase PDO. El constructor acepta parámetros
para especificar el origen de datos (conocido como DSN) y, opcionalmente, el nombre
de usuario y la contraseña.
|
<?php
$gbd = new PDO('mysql:host=localhost;dbname=test', $usuario, $contraseña); ?> |
Si hubiera errores de conexión, se
lanzará un objeto PDOException. Se puede capturar la excepción si
fuera necesario manejar la condición del error, o se podría optar por dejarla
en manos de un gestor de excepciones global de una aplicación configurado
mediante set_exception_handler().
|
<?php
try { $gbd = new PDO('mysql:host=localhost;dbname=test', $usuario, $contraseña); foreach($gbd->query('SELECT * from FOO') as $fila) { print_r($fila); } $gbd = null; } catch (PDOException $e) { print "¡Error!: " . $e->getMessage() . "<br/>"; die(); } ?> |
Una vez realizada con éxito una conexión a la base de datos, será devuelta una instancia de la clase PDO al script. La conexión permanecerá activa durante el tiempo de vida del objeto PDO.
Para cerrar la conexión, es necesario
destruir el objeto asegurándose de que todas las referencias a él existentes
sean eliminadas (esto se puede hacer asignando NULL a la variable que
contiene el objeto). Si no se realiza explícitamente, PHP cerrará
automáticamente la conexión cuando el script finalice.
|
<?php
$gbd = new PDO('mysql:host=localhost;dbname=test', $usuario, $contraseña); // Use la conexión aquí // ya se ha terminado; la cerramos $gbd = null; ?> |
Muchas aplicaciones web se beneficiarán del uso de conexiones persistentes a servidores de bases de datos. Las conexiones persistentes no son cerradas al final del script, sino que son almacenadas en caché y reutilizadas cuando otro script solicite una conexión que use las mismas credenciales. La caché de conexiones persistentes permite evitar la carga adicional de establecer una nueva conexión cada vez que un script necesite comunicarse con la base de datos, dando como resultado una aplicación web más rápida.
|
<?php
$gbd = new PDO('mysql:host=localhost;dbname=test', $usuario, $contraseña, array( PDO::ATTR_PERSISTENT => true )); ?> |
Transacciones
Una vez realizada una conexión a través
de PDO, es necesario comprender cómo PDO gestiona las transacciones antes de
comenzar a realizar consultas. Si no se han manejado anteriormente
transacciones, estas ofrecen cuatro características principales: Atomicidad,
Consistencia, Aislamiento y Durabilidad (ACID por sus siglas en inglés).
En términos sencillos, cualquier trabajo
llevado a cabo en una transacción, incluso si se hace por etapas, se garantiza
que será aplicado a la base de datos de forma segura, y sin interferencia de
otras conexiones, cuando sea consignado ('commit'). El trabajo transaccional
puede también ser deshecho automáticamente bajo petición (siempre y cuando no
se haya consignado), lo que hace más sencillo el manejo de errores en los scripts.
Las transacciones son implementadas
típicamente para hacer que el lote de cambios se aplique a la vez; esto tiene
el buen efecto secundario de mejorar drásticamente la eficiencia de las
actualizaciones. En otras palabras, las transacciones pueden hacer los scripts
más rápidos y potencialmente más robustos.
Desafortunadamente, no todas las bases
de datos admiten transacciones, por lo que PDO necesita ser ejecutado en lo que
es conocido como el modo "auto-commit" cuando se abra por primera vez
la conexión. El modo auto-commit significa que toda consulta que se ejecute
tiene su propia transacción implícita, si la base de datos lo admite, o ninguna
transacción si la base de datos no las admite. Si fuera necesario el uso de
transacciones, se debe usar el método PDO::beginTransaction()
para
iniciar una. Si el controlador subyacente no admite transacciones, se lanzará
una PDOException (independientemente de la configuración del manejo de errores:
esto es siempre una condición de error serio). Una vez que se esté en una
transacción, se puede usar PDO::commit()
o PDO::rollBack() para finalizarla, dependiendo
del éxito del código que se ejecute durante la transacción.
Cuando el script finaliza o cuando una
conexión está a punto de ser cerrada, si existe una transacción pendiente, PDO
la revertirá automáticamente. Esto es una medida de seguridad que ayuda a
evitar inconsistencia en los casos donde el script finaliza inesperadamente (si
no consignó la transacción, se asume que algo salió mal, con lo cual se realiza
la reversión para la seguridad de los datos).
|
<?php
try { $gbd = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2', array(PDO::ATTR_PERSISTENT => true)); echo "Conectado\n"; } catch (Exception $e) { die("No se pudo conectar: " . $e->getMessage()); } try { $gbd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $gbd->beginTransaction(); $gbd->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')"); $gbd->exec("insert into salarychange (id, amount, changedate) values (23, 50000, NOW())"); $gbd->commit(); } catch (Exception $e) { $gbd->rollBack(); echo "Fallo: " . $e->getMessage(); } ?> |
En el ejemplo anterior, se asume que se ha creado un conjunto de entradas para un nuevo empleado, al cual se le ha asignado el número de ID 23. Además de introducir los datos básicos de una persona, también es necesario registrar su sueldo. Es bastante simple hacer dos actualizaciones independientes, pero encerrándolas en las llamadas PDO::beginTransaction() y PDO::commit(), se garantiza que nadie más será capaz de ver los cambios hasta que se hayan completado. Si algo sale mal, el bloque catch revierte los cambios realizados desde que se creó la transacción, y luego muestra el mensaje de error.
Sentencias preparadas y procedimientos almacenados
Muchas de las bases de datos más maduras admiten el
concepto de sentencias preparadas. Estas pueden definirse como un tipo de
plantillas compiladas para SQL que las aplicaciones quieren ejecutar, que
pueden ser personalizadas usando parámetros de variables. Las sentencias
preparadas ofrecen dos grandes beneficios:
- La
consulta sólo necesita ser analizada (o preparada) una vez, pero puede ser
ejecutada múltiples veces con los mismos o diferentes parámetros. Cuando
la consulta es preparada, la base de datos analizará, compilará y
optimizará su plan para ejecutarla. Para consultas complejas, este proceso
puede tomar suficiente tiempo como para que ralentice notablemente una
aplicación si fuera necesario repetir la misma consulta muchas veces con
los mismos parámetros. Usando una sentencia preparada, la aplicación evita
repetir el ciclo de análisis/compilación/optimización. Esto significa que
las sentencias preparadas usan menos recursos y se ejecutan más
rápidamente.
- Los
parámetros para las sentencias preparadas no necesitan estar
entrecomillados; el controlador automáticamente se encarga de esto. Si una
aplicación usa exclusivamente sentencias preparadas, el desarrollador
puede estar seguro de que no ocurrirán inyecciones SQL (sin embargo, si
otras partes de la consulta se construyen con datos de entrada sin
escapar, las inyecciones SQL pueden ocurrir).
Las sentencias preparadas son tan útiles que son la
única característica que PDO emulará para los controladores que no las admitan.
Esto asegura que una aplicación sea capaz de usar el mismo paradigma de acceso
a datos independientemente de las capacidades de la base de datos.
Ejemplo
#6: Inserciones reiteradas usando sentencias preparadas
Este ejemplo realiza dos consultas de tipo INSERT
sustituyendo name y value por los valores correspondientes.
|
<?php
$sentencia = $gbd->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)"); $sentencia->bindParam(1, $nombre); $sentencia->bindParam(2, $valor); // insertar una fila $nombre = 'uno'; $valor = 1; $sentencia->execute(); // insertar otra fila con diferentes valores $nombre = 'dos'; $valor = 2; $sentencia->execute(); ?> |
|
<?php
$sentencia = $gbd->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)"); $sentencia->bindParam(':name', $nombre); $sentencia->bindParam(':value', $valor); // insertar una fila $nombre = 'uno'; $valor = 1; $sentencia->execute(); // insertar otra fila con diferentes valores $nombre = 'dos'; $valor = 2; $sentencia->execute(); ?> |
Ejemplo #7: Inserciones reiteradas usando sentencias preparadas
Ejemplo #8: Obtener datos usando sentencias preparadas
Este
ejemplo obtiene datos basándose en un valor de clave proporcionado por un
formulario. Los datos de usuario son automáticamente entrecomillados, con lo
cual no hay riesgo de un ataque por inyección SQL.
|
<?php
$sentencia = $gbd->prepare("SELECT * FROM REGISTRY where name = ?"); if ($sentencia->execute(array($_GET['name']))) { while ($fila = $sentencia->fetch()) { print_r($fila); } } ?> |
Si el controlador de la base de datos lo admite, una aplicación podría también vincular parámetros para salida y para entrada. Los parámetros de salida son típicamente usados para recuperar valores de procedimientos almacenados. Los parámetros de salida son ligeramente más complejos de usar que los de entrada, de manera que el desarrollador debe saber lo grande que podría ser un parámetro dado cuando se vincula. Si el valor resulta ser más grande que el tamaño que indica, se emitirá un error.
|
<?php
$sentencia = $gbd->prepare("CALL sp_returns_string(?)"); $sentencia->bindParam(1, $valor_devuleto, PDO::PARAM_STR, 4000); // llamar al procedimiento almacenado $sentencia->execute(); print "El procedimiento devolvió $valor_devuleto\n"; ?> |
Ejemplo #9: Llamar a un procedimiento almacenado con un parámetro de salida
Los desarrolladores podrían también especificar parámetros que contienen valores tanto de entrada como de salida; la sintaxis es similar a la de los parámetros de salida. En el siguiente ejemplo, la cadena 'hola' es pasada al procedimiento almacenado, y cuando éste finaliza, 'hola' es reemplazada con el valor de retorno del procedimiento.
Ejemplo
#10: Llamar a un procedimiento almacenado con un parámetro de entrada/salida
|
<?php
$sentencia = $gbd->prepare("SELECT * FROM REGISTRY where name LIKE '%?%'"); $sentencia->execute(array($_GET['name'])); // los parámetros de sustitución deben usarse en el lugar del valor completo $sentencia = $gbd->prepare("SELECT * FROM REGISTRY where name LIKE ?"); $sentencia->execute(array("%$_GET[name]%")); ?> |
|
<?php
$sentencia = $gbd->prepare("CALL sp_takes_string_returns_string(?)"); $valor = 'hola'; $sentencia->bindParam(1, $valor, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000); // llamar al procedimiento almacenado $sentencia->execute(); print "procedure returned $valor\n"; ?> |
Ejemplo #11: Uso inválido de un parámetro de sustitución
Errores y su
manejo
PDO ofrece tres
estrategias diferentes de manejar errores, para adaptarse a su estilo de
desarrollo de aplicaciones.
·
PDO::ERRMODE_SILENT
Este es el modo
predeterminado. PDO simplemente establecerá él mismo el código de error para su
inspección usando los métodos PDO::errorCode() y PDO::errorInfo() tanto en objetos de sentencias como de
bases de datos. Si el error resultó de una llamada sobre un objeto de
sentencia, se deberá invocar al métodoPDOStatement::errorCode() o PDOStatement::errorInfo() sobre dicho objeto. Si el error resultó de
una llamada sobre un objeto de bases de datos, se deberá invocar, en su lugar,
a los métodos del objeto de bases de datos.
·
PDO::ERRMODE_WARNING
Además de establecer el
código de error, PDO emitirá un mensaje E_WARNING tradicional. Esta
configuración es útil durante la depuración o las pruebas, si lo que se quiere
es ver qué problemas han ocurrido, sin interrumpir el flujo de la aplicación.
·
PDO::ERRMODE_EXCEPTION
Además de establecer el
código de error, el PDO lanzará una excepción de tipo PDOException y establecerá sus propiedades para
reflejar el error y la información del mismo. Esta configuración también es
útil durante la depuración, ya que, de hecho, señalará el lugar del error del
script, apuntando a áreas potencialmente problemáticas del código (recuerde:
las transacciones son automáticamente revertidas si la excepción causa que
finalice el script).
El modo 'Exception' también
es útil porque se puede estructurar el manejo de errores con más claridad que
con el estilo tradicional de advertencias de PHP, y con menos código/anidación
que con la ejecución en modo silencioso y comprobando explícitamente el valor
devuelto de cada llamada a la base de datos.
|
<?php
$dsn = 'mysql:dbname=testdb;host=127.0.0.1'; $usuario = 'usuario'; $contraseña = 'contraseña'; try { $gbd = new PDO($dsn, $usuario, $contraseña); $gbd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { echo 'Falló la conexión: ' . $e->getMessage(); } ?> |
|
<?php
$dsn = 'mysql:dbname=test;host=127.0.0.1'; $user = 'usuario'; $password = 'contraseña'; /* Usando try/catch en el constructor sigue siendo válido aunque se establezca ERRMODE a WARNING desde PDO::__construct siempre lanzará una PDOException si la conexión falla. */ try { $dbh = new PDO($dsn, $user, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING)); } catch (PDOException $e) { echo 'Error de conexión: ' . $e->getMessage(); exit; } // Esto hará que PDO lance un error de nivel E_WARNING en lugar de una excepción (cuando la tabla no exista) $dbh->query("SELECT columnaincorrecta FROM tablaincorrecta"); ?> |
Warning: PDO::query(): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.tablaincorrecta' doesn't exist in
/tmp/pdo_test.php on
line 18
|
El resultado sería:
La clase PDO
Representa una
conexión entre PHP y un servidor de bases de datos.
|
PDO {
}
|
CONTENIDOS DE LA CLASE
|
|
PDO::beginTransaction
|
Inicia una
transacción
|
PDO::commit
|
Consigna una transacción
|
PDO::__construct
|
Crea una
instancia de PDO que representa una conexión a una base de datos
|
PDO::errorCode
|
Obtiene un SQLSTATE asociado con la última
operación en el manejador de la base de datos
|
PDO::errorInfo
|
Obtiene
información extendida del error asociado con la última operación del
manejador de la base de datos
|
PDO::exec
|
Ejecuta una sentencia SQL y devuelve el
número de filas afectadas
|
PDO::getAttribute
|
Devuelve un
atributo de la conexión a la base de datos
|
PDO::getAvailableDrivers
|
Devuelve un array con los controladores de
PDO disponibles
|
PDO::inTransaction
|
Comprueba si
una transacción está activa
|
PDO::lastInsertId
|
Devuelve el ID de la última fila o secuencia
insertada
|
PDO::prepare
|
Prepara una
sentencia para su ejecución y devuelve un objeto sentencia
|
PDO::query
|
Ejecuta una sentencia SQL, devolviendo un
conjunto de resultados como un objeto PDOStatement
|
PDO::quote
|
Entrecomilla
una cadena de caracteres para usarla en una consulta
|
PDO::rollBack
|
Revierte una transacción
|
PDO::setAttribute
|
Establece un
atributo
|
Controladores de PDO
Nombre
del controlador
|
Bases
de datos admitidas
|
PDO_CUBRID
|
Cubrid
|
PDO_DBLIB
|
FreeTDS / Microsoft SQL Server / Sybase
|
PDO_FIREBIRD
|
Firebird
|
PDO_IBM
|
IBM DB2
|
PDO_INFORMIX
|
IBM
Informix Dynamic Server
|
PDO_MYSQL
|
MySQL
3.x/4.x/5.x
|
PDO_OCI
|
Oracle
Call Interface
|
PDO_ODBC
|
ODBC v3 (IBM DB2, unixODBC and win32 ODBC)
|
PDO_PGSQL
|
PostgreSQL
|
PDO_SQLITE
|
SQLite 3 and
SQLite 2
|
PDO_SQLSRV
|
Microsoft SQL Server / SQL Azure
|
PDO_4D
|
4D
|
PDO::commit
|
public bool PDO::commit ( void )
|
Consigna una transacción, devolviendo la conexión a la base
de datos al modo 'autocommit' hasta que la siguiente llamada
a PDO::beginTransaction() inicie una nueva transacción.
Valores devueltos
Devuelve TRUE en
caso de éxito o FALSE en caso de error.
|
<?php
/* Iniciar una transacción, desactivando 'autocommit' */ $gbd->beginTransaction(); /* Insertar múltiples registros en base a "todo o nada" */ $sql = 'INSERT INTO fruit (name, colour, calories) VALUES (?, ?, ?)'; $gsent = $gbd->prepare($sql); foreach ($frutas as $fruta) { $gsent->execute(array( $fruta->name, $fruta->colour, $fruta->calories, )); } /* Consignar los cambios */ $gbd->commit(); /* La conexión a la base de datos ahora a vuelto al modo 'autocommit' */ ?> |
|
<?php
/* Iniciar una transacción, desactivando 'autocommit' */ $gbd->beginTransaction(); /* Cambiar el esquema de la base de datos */ $gsent = $gbd->exec("DROP TABLE fruit"); /* Consignar los cambios */ $gbd->commit(); /* La conexión a la base de datos ahora a vuelto al modo 'autocommit' */ ?> |
PDO::rollBack
|
public bool PDO::rollBack ( void )
|
Revierte la transacción actual, que fue iniciada por PDO::beginTransaction(). Se lanzará una excepción de tipoPDOException si no hay ninguna transacción activa.
Si la base de datos se estableció al
modo 'autocommit', esta función restablecerá el modo 'autocommit' después de
haber revertido la transacción.
Algunas bases de datos, incluyendo
MySQL, ejecutan un COMMIT implícito cuando una sentencia de lenguaje de
definición de base de datos (DDL), como DROP TABLE o CREATE TABLE, se ejecuta
dentro de una transacción. El COMMIT implícito pevendrá de revertir cualquier
otro cambio dentro de los límites de la transacción.
Valores devueltos
Devuelve TRUE en
caso de éxito o FALSE en caso de error.
Ejemplo #16 Revertir
una transacción
|
<?php
/* Comenzar una transacción, desactivando el modo 'autocommit' */ $gbd->beginTransaction(); /* Cambiar el esquema y los datos de la base de datos */ $sth = $gbd->exec("DROP TABLE fruit"); $sth = $gbd->exec("UPDATE dessert SET name = 'hamburger'"); /* Reconocer el error y revertir los cambios */ $gbd->rollBack(); /* Ahora la conexión a la base de datos a vuelto al modo 'autocommit' */ ?> |
buena explicacion, pesimo fondo, mil gracias
ResponderEliminar