Como trabajar con una base de datos utilizando PDO
Hace varíos años ya hablé en este blog sobre como interactuar con una base de datos con MySQLi pero quería agregar una nueva entrada sobre la implementación de la clase PDO ya que parece ser mejor y es la que suelo utilizar hoy en día para mis desarrollos y me gustaría dártela a conocer junto con sus beneficios.
¿Qué es PDO?
PDO tiene como significado PHP Data Objects, una extensión para acceder a bases de datos con PHP con la ventaja de que permite acceder con un controlador específico.
Cada servidor tiene disponible diversos controladores que puedes revisar ejecutando la siguiente función:
print_r(PDO::getAvailableDrivers());
Por ejemplo, al ejecutar la función anterior en un servidor local usando Xampp tenemos como resultado:
Esto significa que en Xampp puede trabajar con 2 motores de base de datos diferentes: mysql y sqlite.
¿Cómo conectar a la base de datos con PDO?
Yo suelo crear una clase que tenga un método para conectar con la base de datos.
Algo como lo siguiente:
class Db
{
public static function connect()
{
$link = false;
try {
$link = new PDO(
"mysql:host=localhost;dbname=nombrebasededatos",
"root",
"",
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")
);
} catch (PDOException $e){
echo $e->getMessage();
}
return $link;
}
}
Usando la estructura de un try {} catch() {}, estamos intentando crear una instancia de la clase PDO con 4 parámetros:
- En el primer parámetro se define una cadena con el controlador que estamos utilizando, en este caso mysql, el servidor con host=localhost y la base de datos con dbname=nombrebasededatos.
- El segundo parámetro es el nombre de usuario que conecta a la base de datos.
- El tercer parámetro es la contraseña. En nuestro caso, vacía porque estamos trabajando en localhost con Xampp y por defecto la contraseña es vacía.
- Y en el cuarto parámetro definimos un array con las excepciones y el parse con UTF8 para guardar en base de datos sin problemas caracteres latinos como acentos y ñ.
Si la conexión es fallida, se ejecutará el catch para mostrar el error correspondiente y si la conexión es excitosa se retornará el enlace a la conexión para poder operar con la base de datos.
¿Como obtener una columna de una tabla de la base de datos con PDO?
Siguiendo con la misma estructura de un try {} catch() {}, podemos retornar el valor de una columna.
En la misma clase u otra podemos hacer lo siguiente para obtener un valor de una tabla:
public static function getNumProducts()
{
try {
$statement = Db::connect()->prepare(
'SELECT COUNT(*)
FROM product'
);
$statement->setFetchMode(PDO::FETCH_ASSOC);
$statement->execute();
return $statement->fetchColumn();
} catch (PDOException $e){
return $e->getMessage();
}
}
Esta función retorna el número de filas que hay en nuestra tabla de productos.
Conectamos con la base de datos y preparamos la consulta.
Definimos el modo asociativo, ejecutamos la consulta y retornamos el valor con fetchColumn() que justamente devuelve lo que necesitamos, una única columna con el número de productos.
Esta misma consulta se podría usar con rowCount() de la siguiente forma:
$statement = Db::connect()->prepare('SELECT * FROM product');
$statement->execute();
return $statement->rowCount();
¿Como obtener varias o todas las filas de una tabla de la base de datos con PDO?
De la misma forma pero usando la función fetchAll() podemos recuperar varias filas:
public static function getProducts()
{
try {
$statement = Db::connect()->prepare(
'SELECT *
FROM product'
);
$statement->setFetchMode(PDO::FETCH_ASSOC);
$statement->execute();
return $statement->fetchAll();
} catch (PDOException $e){
return $e->getMessage();
}
}
Si hay datos, esta función retorna un array con todas las columnas que podemos recorrer con un foreach.
Insertar un registro con PDO
Podemos ejecutar la consultar para insertar elementos y obtener el identificador del registro con lastInsertId() tal y como sigue:
$statement = Db::connect()->prepare('INSERT INTO product (name) VALUES ("'.(string)$name.'")');
$statement->execute();
echo $statement->lastInsertId();
Modificar un registro con PDO
De la misma forma podemos modificar un registro con PDO:
$statement = Db::connect()->prepare('UPDATE product SET name = "'.(string)$name.'"');
$statement->execute();
Eliminar un registro con PDO
$sql = 'DELETE FROM product WHERE id_product = '.$this->id;
$statement = Db::connect()->prepare($sql);
return $statement->execute();
¿Porqué usar PDO en vez de MySQLi?
MySQLi es una extensión de PHP que fue creada en su momento para facilitar la comunicación entre el código PHP y un servidor MySQL.
MySQLi es la extensión heredera de MySQL que ya quedó obsoleta hace varios años.
Esta extensión mejoró la extensión de MySQL agregando la ventaja de trabajar con la programación orientada a objetos.
La principal ventaja que tiene PDO sobre MySQLi es la habilidad de poder conectar con diferentes controladores de bases de datos.
Es decir, con MySQLi solo puedes conectar a bases de datos que utilice MySQL.
En cambio, con PDO tienes muchas más posibilidades que hacen que tu aplicación sea mucho más escalable y poder ejecutarse en distintos entornos o dispositivos.
Además, si algún día decides migrar tu aplicación a otro motor de base de datos diferentes, el cambio es trivial ya que tan solo tienes que cambiar un dato en la conexión.
Por ejemplo, si inicialmente decidiste crear tu aplicación usando el motor de base de datos «mysql», la conexión con la base de datos la hiciste de la siguiente manera:
$link = new PDO("mysql:host=localhost;dbname=nombrebasededatos", "root", "");
Si llegó un día que decidiste cambiar al motor de base de datos a «sqlite». Tan solo tienes que hacer un mínimo cambio en tu aplicación:
$link = new PDO("sqlite:host=localhost;dbname=nombrebasededatos", "root", "");
El resto de la aplicación seguirá funcionando como hasta ahora.
Con MySQLi los cambios no son tran triviales y se requiere un esfuerzo superior para adaptar tu aplicación al cambio.
Conclusiones
Con este artículo no quiero sugestionarte para que utilices PDO si o si.
Tu debes decidir que es mejor para tu desarrollo y sobretodo usa lo que te haga sentir más feliz.
En cualquier caso, debes preguntarte si es posible que algún día pueda darse el caso de que tu aplicación cambiará de motor de base de datos.
Si piensas que no, puedes usar cualquiera de las 2 pero si existe la duda, te recomiendo que uses PDO para que el día que llegue el cambio sea rápido y no pierdas más tiempo del deseado.
¿Y tu que opinas? ¿Qué extensión usas para conectar con la base de datos en tus aplicaciones?
Deja una respuesta