martes, 16 de diciembre de 2014

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




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

Estas constantes están definidas por esta extensión y estarán disponibles sólo cuando la extensión haya sido compilada con PHP, o bien sea cargada dinámicamente en ejecución.

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);
?>
Ejemplo #1: Conectarse a MySQL
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();
}
?>
Ejemplo #2: Manejo de errores de conexión

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;
?>
Ejemplo #3: Cerrar una conexión

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
));
?>
Ejemplo #4: Conexiones persistentes




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_ERRMODEPDO::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();
}
?>
Ejemplo #5: Ejecución de un lote en una transacción

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_devuletoPDO::PARAM_STR4000);

// 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$valorPDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT4000);

// 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_ERRMODEPDO::ERRMODE_EXCEPTION);
} catch (
PDOException $e) {
    echo 
'Falló la conexión: ' $e->getMessage();
}

?>
Ejemplo #12: Crear una instancia de PDO y establecer el modo de error


<?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");
?>
Ejemplo #13: Crear una instancia PDO y establecer el modo de error desde el constructor

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 {
public __construct ( string $dsn [, string $username [, string $password [, array $options]]] )
public bool beginTransaction ( void )
public bool commit ( void )
public mixed errorCode ( void )
public array errorInfo ( void )
public int exec ( string $statement )
public mixed getAttribute ( int $attribute )
public static array getAvailableDrivers ( void )
public bool inTransaction ( void )
public string lastInsertId ([ string $name = NULL ] )
public PDOStatement prepare ( string $statement [, array $driver_options = array() ] )
public PDOStatement query ( string $statement )
public string quote ( string $string [, int $parameter_type = PDO::PARAM_STR ] )
public bool rollBack ( void )
public bool setAttribute ( int $attribute , mixed $value )
}
Sinopsis de la clase




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 )
PDO::commit — Consigna una transacción
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' */
?>
Ejemplo #14: Consignar una transacción básica






<?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' */
?>
Ejemplo #15: Consignar una transacción DDL


PDO::rollBack


public bool PDO::rollBack ( void )
PDO::rollBack — Revierte una transacción

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' */
?>
El siguiente ejemplo comienza una transacción y ejecuta dos sentencias que modifican la base de datos antes de revertir los cambios. En MySQL, sin embargo, la sentencia DROP TABLE consigna automáticamente la transacción, por lo que no son revertidos ninguno de los cambios en la transacción.


1 comentario: