PDO (PHP Data Objects) es una extensión para acceder a bases de datos. PDO permite conectar con distintos sistemas de bases de datos con un único controlador (MySQL, Oracle, Mongodb,…).
Para realizar una consulta desde PHP a mysql con PDO deberemos seguir los siguientes pasos:
Conexión a nuestra base de datos mediante 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 la base de datos (conocido como DSN) y, opcionalmente, el nombre de usuario y la contraseña (si la hubiera).
$dsn = 'mysql:host=localhost;dbname=prueba'; $username = 'root'; $password = ''; $pdo = new PDO($dsn, $username, $password);
Opcionalmente, podemos agregar atributos para controlar el manejo de errores, etc (se tratará en otro artículo).
Para controlar errores en la conexión podemos hacerlo mediante un try-catch
try { $pdo = new PDO($dsn, $username, $password); } catch (PDOException $e) { echo 'Error en la conexión: ' . $e->getMessage(); die(); }
Preparar y ejecutar consulta desde PHP con PDO
Una vez hecha la conexión podemos preparar la consulta, ejecutarla y realizar el tratamiento de la respuesta recibida, todo esto lo haremos mediante el objeto que hemos obtenido en la conexión PDO.
Para ejecutar una consulta sin datos variables, podemos usar el método query del objeto PDO
$result= $pdo->query('SELECT * FROM coches'); if (!$result) { echo "Error consultando coches"; } else { echo "Tratamiento del array result"; }
Si nuestra consulta depende de otros datos, por ejemplo, datos provenientes de un formulario o datos prepalculados, debemos usar el método prepare.
PDO nos facilita esta labor a nos aporta la seguridad de aplicación necesaria para que no tengamos muchos problemas, los pasos a seguir sería:
PREPARE -> [BIND] -> EXECUTE
Veamos un ejemplo de la primera acción a realizar (prepare), se puede hacer de varias maneras:
Mediante parámetros (:parametro)
// Consulta $consulta = $pdo->prepare('SELECT * FROM coches WHERE nombre = :nombre');
ó mediante interrogantes (?)
// Consulta $consulta = $pdo->prepare('SELECT * FROM coches WHERE nombre = ?');
La diferencia entre ambos es el tratamiento posterior que hagamos.
La parte del proceso BIND es opcional, puesto que lo podemos comprimir todo en la sentencia EXECUTE, veamos como sería haciéndolo directamente en execute.
Si usamos parámetros (:parametro)
// Consulta $consulta = $pdo->prepare('SELECT * FROM coches WHERE nombre =:nombre'); $resultado = $consulta->execute(array(':nombre'=>$nombre));
Si usamos interrogaciones (?), debemos tener cuidado si pasamos varios parámetros, para asignarlos a la posición correcta deberemos hacerlo en orden.
// Consulta $consulta = $pdo->prepare('SELECT * FROM coches WHERE nombre = ? AND color = ?'); $resultado = $consulta->execute([$nombre, $color]);
Vamos a ver como sería sin saltarnos la parte opcional BIND, ya que nos da un mejor control de los parámetros de entrada que recibimos
Una vez realizada la consulta deberemos usar el método bindParam o bindValue, más adelante veremos la diferencia, pero para el ejemplo vamos a usar bindParam.
Cuya sintaxis es la siguiente, donde vemos que tenemos dos parámetros de entrada obligatorios y el resto son opcionales:
public PDOStatement::bindParam( mixed $parameter, mixed &$variable, int $data_type = PDO::PARAM_STR, int $length = ?, mixed $driver_options = ? ): bool
Vamos a hacer uso de los dos primeros parámetros:
// Consulta $consulta = $pdo->prepare('SELECT * FROM coches WHERE nombre =:nombre'); $consulta->bindParam(':nombre', $nombre); $resultado = $consulta->execute();
Si hiciéramos uso de los parámetros opcionales podemos filtrar mucho mejor los parámetros que nos llegan para evitar problemas inesperados en la ejecución de la consulta (ver más abajo que es PDO::PARAM_STR)
// Consulta $consulta = $pdo->prepare('SELECT * FROM coches WHERE nombre =:nombre AND color = :color'); $consulta->bindParam(':nombre', $nombre, PDO::PARAM_STR); $consulta->bindParam(':color', $color, PDO::PARAM_STR, 10); $resultado = $consulta->execute();
Tratamiento de datos obtenidos en una consulta PDO
La consulta de datos obtenidos tras llamar a EXECUTE se realiza mediante fetch, que obtiene la siguiente fila de un conjunto de resultados, o mediante fetchAll que nos devuelve un array con todas las filas del resultado.
Veamos un ejemplo con fetchAll
$miscoches= $resultado->fetchAll(PDO::FETCH_ASSOC); foreach ($miscoches as $coche) { $fila = $coche['matricula'] .'<br/>'. $coche['nombre'].'<br/>'. $coche['color'] .'<br/>'. $coche['cv'].'<br/>'; }
¿Que es el parámetro que estamos pasando a la función fetchAll?
Este parámetro controla como se devuelven los datos, de que forma los obtenemos, las opciones nos valen tanto para fetch como para fetchAll y son:
PDO::FETCH_ASSOC
: devuelve un array asociativoPDO::FETCH_BOTH
(predeterminado): devuelve un array indexado tanto por nombre de columna, como numéricamente con índice de base 0 tal como fue devuelto en el conjunto de resultados.PDO::FETCH_BOUND
PDO::FETCH_CLASS
PDO::FETCH_INTO
PDO::FETCH_LAZY
PDO::FETCH_NAMED
:PDO::FETCH_ASSOC
PDO::FETCH_NUM
PDO::FETCH_OBJ
PDO::FETCH_PROPS_LATE
:
Podemos ver el funcionamiento de cada uno en la documentación oficial de PHP fetch o fecthAll
Uso de data_type
en bindParam
Podemos ver las constantes disponibles en la página oficial de php https://www.php.net/manual/es/pdo.constants.php