PDO vs MySQLi en PHP
CategoriasBases de datosPHPProgramación

PDO vs MySQLi en PHP: ¿Cuál elegir y por qué?

En este articulo vamos hablar sobre estas dos fantásticas extensiones PHP para conectar a una base de datos.

Cuando estamos comenzando a programar en PHP y llega el momento en que necesitamos conectar nuestra aplicación web a una base de datos, normalmente o casi siempre, se empieza con la base de datos MySQL. Puedes encontrar muchos tutoriales que hablan de: “como conectar PHP y MySQL” entre otros miles.

El objetivo de este articulo no es un tutorial más sobre como conectar nuestra aplicación, sino como he dicho al principio, explicar la diferencia de estas dos opciones principales que trae PHP por defecto: PDO (PHP Data Objects) y MySQLi (MySQL Improved).

Ambas extensiones permiten interactuar con bases de datos, pero cada una tiene sus particularidades, ventajas y limitaciones. Así que en este artículo vamos a explicar de forma clara y con ejemplos cuál deberías elegir, especialmente si estás dando tus primeros pasos con PHP ❤️​

¿Qué es MySQLi?

MySQLi es una extensión mejorada para trabajar con bases de datos MySQL.

¿Por qué mejorada?

Porque antes, en los tiempos jurásicos de PHP (vale, no tanto, pero casi), se usaba la extensión mysql a secas para conectarse a bases de datos MySQL y, esta extensión funcionaba bien para la época, pero finalmente se quedó limitada, ya que no soportaba características modernas como: consultas preparadas, soporte nativo de objetos, soporte para múltiples declaraciones (multi-queries) y control más estricto de errores.

La extensión mysql quedó obsoleta a partir de PHP 5.5.0 y finalmente eliminada en PHP 7.0.

Es así como surgió MySQLi (MySQL Improved). Básicamente es la evolución moderna y mejorada de la antigua extensión mysql, ofreciendo actualmente una interfaz orientada a objetos, pero permitiendo también un estilo procedimental.

¿Qué es PDO?

PDO es una extensión que nos ofrece una interfaz más genérica para acceder a diferentes bases de datos a través de una única clase. Esto significa que podemos usar MySQL, PostgreSQL, SQLite o cualquier otro motor compatible sin reescribir gran parte del código.

Como seguro has deducido ya, tanto MySQLi como PDO tienen algunas ventajas y desventajas, haciendo casi mejor PDO, aunque no estamos comparando MySQLi vs PDO.

Ventajas y desventajas de MySQLi

La principal ventaja de MySQLi es que ofrece un mejor rendimiento que su antecesor MySQL.

Por otro lado, soporta consultas preparadas, multi-querys (varias consultas SQL al mismo tiempo en una sola llamada) y podemos usarlo de forma procedimental y orientada a objetos.

La mayor desventaja de MySQLi, y ahora sí lo comparamos con PDO, es que solo funciona con bases de datos MySQL.

Ventajas y desventajas de PDO

PDO por su parte, nos ofrece la posibilidad de trabajar con varios motores de bases de datos (MySQL, PostgreSQL, SQLite, etc.).

Es exclusivamente orientado a objetos.

Soporta consultas preparadas con mayor facilidad.

Ofrece una mayor seguridad ante ataques de inyección SQL.

Su principal y única “desventaja”, es que no soporta algunas funciones específicas de MySQL (concretamente las multi_query()).

Vale, ahora, vista la teórica, ¿un poco de práctica no?

Ejemplo MySQLi

Empecemos con el ejemplo más básico de todos: conectar PHP con MySQL.

Conexión y consulta con MySQLi (estilo procedimental)

<?php
// Conexión
$conexion = mysqli_connect("localhost", "usuario", "contraseña", "nombre_base_de_datos");

if (!$conexion) {
    die("Error de conexión: " . mysqli_connect_error());
}

// Consulta
$resultado = mysqli_query($conexion, "SELECT * FROM usuarios");

// Mostrar resultados
while ($fila = mysqli_fetch_assoc($resultado)) {
    echo $fila['nombre'] . "<br>";
}

// Cerrar conexión
mysqli_close($conexion);

Como ves, usamos las funciones de MySQLi para conectar a la base de datos.

La ventaja de este estilo, es que es más lineal y directo, por lo que muchos principiantes lo entienden fácilmente.

La desventaja, sin embargo, es que no es tan robusto ni escalable como el enfoque que veremos a continuación, el orientado a objetos.

Si eres muy principiante y aún no has tocado lo que es la programación orientada a objetos, tranqui, el siguiente ejemplo no tiene misterio 👻

Conexión y consulta con MySQLi (estilo orientado a objetos)

<?php
$mysqli = new mysqli("localhost", "usuario", "contraseña", " nombre_base_de_datos");

if ($mysqli->connect_error) {
    die("Error de conexión: " . $mysqli->connect_error);
}

$resultado = $mysqli->query("SELECT * FROM usuarios");

while ($fila = $resultado->fetch_assoc()) {
    echo $fila['nombre'] . "<br>";
}

$mysqli->close();

Como ves es igual al anterior, pero con estilo orientado a objetos.

¿Cuál de los dos debes usar?

En primer lugar, el que te salga… ¡ui, perdón! 🤭

Profesionalmente hablando, como recomendación, personalmente recomiendo el uso del estilo orientado a objetos (POO), incluso aunque seas nuevo en PHP y estes dando tus primeros pasos.

¿Por qué digo eso?

Porque si no lo sabes aún, la POO, mejora la organización del código (mira ambos ejemplos) y, por otro lado, al usar objetos nos permite encapsular mejor las conexiones, consultas y operaciones en estructuras más limpias y reutilizables (qué importante es esto la verdad 😏).

El código es más legible y mantenible cuando se sigue un enfoque orientado a objetos, pero no acaba aquí; nos permite también llevar mejor el manejo de los errores facilitando el usar excepciones (try/catch) y en definitiva, aprender este enfoque/estilo desde un principio te prepara mejor 😉

Entonces… el estilo procedimental ¿“pa cuándo”?

Pues solo en casos muy concretos. Por ejemplo, para scripts pequeños o “simplones” pero ¿la verdad? No lo uses nunca. Con saber que está ahí y existe es suficiente 😂

Conexión y consulta con PDO

Esta es la mejor manera de conectar hoy en día PHP con cualquier base de datos, ya sea MySQL, SQLite, etc.

<?php
try {
    $pdo = new PDO("mysql:host=localhost;dbname=nombre_base_de_datos", "usuario", "contraseña");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $pdo->query("SELECT * FROM usuarios");

    while ($fila = $stmt->fetch(PDO::FETCH_ASSOC)) {
        echo $fila['nombre'] . "<br>";
    }

} catch (PDOException $e) {
    echo "Error de conexión: " . $e->getMessage();
}

Poco hay que decir sobre el código.

Las ventajas de PDO ya las vimos al principio y como ves, también es orientado a objetos.

En el ejemplo he decidido usar también un bloque try/catch, porque conviene a acostumbrarnos a poner siempre las conexiones a la base de datos dentro de uno, ya que si algo falla se lanza la excepción.

Consultas preparadas

¿Qué son las consultas preparadas?

Una consulta preparada es una forma segura y eficiente de ejecutar sentencias SQL que contienen valores dinámicos (como datos introducidos por el usuario).

O sea, vamos a recibir datos que no sabemos “como vienen”.

Por ejemplo, si queremos comprobar un email haremos esto:

$sql = "SELECT * FROM usuarios WHERE email = '$email'";

Pero como acabo de decir, no sabemos cómo vienen, por tanto, quién nos asegura que el email capturado sea pericoeldelospalotes@undominio.com y que no contenga por ejemplo caracteres raros como ‘#/-…”?

Pues para eso están las consultas preparadas!

Entonces, en lugar de escribir el código anterior hacemos lo siguiente:

$sql = "SELECT * FROM usuarios WHERE email = ?";

La diferencia, es que no se insertan directamente los valores dentro del string SQL como el primer ejemplo, sino que la estructura de la consulta se separa de los datos (ahora lo veremos con más detalle). Pero antes de continuar:

¿Para qué sirven exactamente?

  • Lo principal y lo más importante es que evitan las famosas inyecciones SQL (hoy en día ya no tan famosas quizá). Al separar los datos del SQL, evitamos que cualquier persona malintencionada pueda manipular la consulta con entradas maliciosas.
  • Por otro lado, mejoramos el rendimiento. Por ejemplo, si vamos a ejecutar muchas veces la misma consulta con distintos valores, el motor de la base de datos puede reutilizar el plan de ejecución.
  • Ganamos tener un código más limpio y mantenible 😉

Consultas preparadas con MySQLi

<?php

$conexion = new mysqli("localhost", "usuario", "contraseña", "nombre_base_de_datos");

$stmt = $conexion->prepare("SELECT * FROM usuarios WHERE email = ?");
$stmt->bind_param("s", $email); // "s" = string
$email = $_GET['email'];
$stmt->execute();

$resultado = $stmt->get_result();
while ($fila = $resultado->fetch_assoc()) {
    echo $fila['nombre'] . "<br>";
}

Es importante saber, que, si se usa este tipo de consultas, es obligatorio indicar el tipo de cada parámetro a recibir mediante una cadena de formato al llamar a bind_param().

En el ejemplo establecemos la letra “s” que indica que el parámetro $email es una cadena de texto (string).

El orden de las letras debe coincidir exactamente con el orden de los valores que se pasan como argumentos.

Un ejemplo rápido:

$nombre = "Camiseta";
$precio = 19.99;

$stmt = $conexion->prepare("SELECT * FROM productos WHERE nombre = ? AND precio > ?");
$stmt->bind_param("sd", $nombre, $precio); // s = string, d = double
$stmt->execute();

Como vemos, hemos usado “sd”:

  • “s” para el nombre (una cadena)
  • “d” para el precio (un número decimal).

Consultas preparadas con PDO

<?php

$pdo = new PDO("mysql:host=localhost;dbname=nombre_base_de_datos", "usuario", "contraseña");

$stmt = $pdo->prepare("SELECT * FROM usuarios WHERE email = :email");
$stmt->bindParam(":email", $email, PDO::PARAM_STR);
$email = $_GET['email'];
$stmt->execute();

while ($fila = $stmt->fetch(PDO::FETCH_ASSOC)) {
    echo $fila['nombre'] . "<br>";
}

En PDO, a diferencia de MySQLi, no se requiere especificar el tipo de dato a recibir, pero sí que es recomendable hacerlo, aunque como vemos se hace de manera diferente, que es usando constantes predefinidas.

En definitiva, las consultas preparadas son la forma correcta y segura de ejecutar sentencias SQL dinámicas.


Y ya si, para ir finalizando el artículo, recomendarte a nivel personal que si estas iniciando en PHP y solo vas a trabajar con bases de datos MySQL (al menos por ahora) y prefieres una curva de aprendizaje algo más light, MySQLi puede ser una buena elección inicial, eso sí, con estilo orientado a objetos.

Pero, por el contrario, si buscas desde un principio flexibilidad, quieras probar a consultar otras bases de datos y quieres, porque no, hacerlo todo de manera más profesional desde el principio, entonces te recomiendo PDO, ya que te ayudará a desarrollar buenas prácticas 😉

Si tienes cualquier duda o deseas contarme tu experiencia usando PDO o MySQLi ya sabes, te leo en los comentarios o por redes 😀

Sobre el autor

Comparte:

Este artículo está publicado bajo una licencia Creative Commons Atribución-CompartirIgual 4.0 Internacional . Puedes compartirlo y adaptarlo, incluso con fines comerciales, siempre que cites al autor y mantengas esta misma licencia.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Información básica sobre protección de datos
Responsable Óscar Martínez +info...
Finalidad Gestionar y moderar los comentarios +info...
Legitimación Consentimiento del interesado. +info...
Destinatarios No se cederán datos a terceros, salvo obligación legal +info...
Derechos Acceder, rectificar y cancelar los datos, así como otros derechos. +info...
Información adicional Puedes consultar la información adicional y detallada sobre protección de datos en nuestra página de política de privacidad.

Este sitio esta protegido por reCAPTCHA y laPolítica de privacidady losTérminos del servicio de Googlese aplican.

El periodo de verificación de reCAPTCHA ha caducado. Por favor, recarga la página.