Taller > PHP > Base de Datos MySQL
Uso de Sentencias Preparadas en PHP con MySQLi
Las sentencias preparadas en PHP son una herramienta crucial para mejorar la seguridad y eficiencia en el manejo de bases de datos. Estas son especialmente útiles para prevenir ataques de inyección SQL, uno de los problemas más comunes en el desarrollo web.
¿Qué son las sentencias preparadas?
Una sentencia preparada es una plantilla de consulta SQL que se envía al servidor de la base de datos y se almacena para su posterior ejecución. La ventaja principal es que los valores que se insertarán en la consulta no se incluyen en el momento de la preparación, lo que permite ejecutar la misma consulta varias veces con diferentes valores.
Ventajas de las sentencias preparadas
Seguridad contra inyecciones SQL: Al utilizar parámetros vinculados, evitamos la posibilidad de que se inyecten comandos maliciosos en la base de datos.
Eficiencia: El motor de la base de datos prepara la consulta una sola vez, lo que reduce el tiempo de procesamiento cuando se ejecuta varias veces.
Reducción de errores: Al separar la consulta de los datos, es menos probable que se produzcan errores debido a problemas de formato en los valores.
Uso de sentencias preparadas con MySQLi
A continuación, veremos cómo utilizar sentencias preparadas en MySQLi (estilo orientado a objetos) para insertar registros en una tabla llamada usuarios.
Ejemplo de Sentencia Preparada con MySQLi
<?php
$servidor = "localhost";
$usuario = "root";
$contraseña = "";
$base_datos = "empresa";
// Crear conexión
$conexion = new mysqli($servidor, $usuario, $contraseña, $base_datos);
// Verificar conexión
if ($conexion->connect_error) {
die("Conexión fallida: " . $conexion->connect_error);
}
// Preparar la sentencia SQL
$stmt = $conexion->prepare("INSERT INTO usuarios (nombre, apellido, email) VALUES (?, ?, ?)");
// Vincular parámetros
$stmt->bind_param("sss", $nombre, $apellido, $email);
// Insertar primer registro
$nombre = "Luis";
$apellido = "Ramírez";
$email = "luis@ejemplo.com";
$stmt->execute();
// Insertar segundo registro
$nombre = "Carla";
$apellido = "Martínez";
$email = "carla@ejemplo.com";
$stmt->execute();
// Insertar tercer registro
$nombre = "Pedro";
$apellido = "Gómez";
$email = "pedro@ejemplo.com";
$stmt->execute();
echo "Registros insertados exitosamente";
// Cerrar la conexión y la sentencia
$stmt->close();
$conexion->close();
?>
Explicación del código
prepare(): Prepara una plantilla de consulta SQL con marcadores de posición (?).
bind_param(): Vincula los parámetros a la consulta, especificando el tipo de dato (sss indica tres cadenas).
execute(): Ejecuta la consulta con los valores vinculados.
Uso de sentencias preparadas con PDO
El siguiente ejemplo utiliza PDO (PHP Data Objects) para lograr el mismo resultado que con MySQLi, pero con un enfoque ligeramente diferente.
Ejemplo de Sentencia Preparada con PDO
<?php
$servidor = "localhost";
$usuario = "root";
$contraseña = "";
$base_datos = "empresa";
try {
// Crear conexión
$conexion = new PDO("mysql:host=$servidor;dbname=$base_datos", $usuario, $contraseña);
// Configurar PDO para que lance excepciones en caso de error
$conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Preparar la sentencia SQL
$stmt = $conexion->prepare("INSERT INTO usuarios (nombre, apellido, email) VALUES (:nombre, :apellido, :email)");
// Vincular parámetros
$stmt->bindParam(':nombre', $nombre);
$stmt->bindParam(':apellido', $apellido);
$stmt->bindParam(':email', $email);
// Insertar primer registro
$nombre = "Ana";
$apellido = "López";
$email = "ana@ejemplo.com";
$stmt->execute();
// Insertar segundo registro
$nombre = "Marcos";
$apellido = "Hernández";
$email = "marcos@ejemplo.com";
$stmt->execute();
// Insertar tercer registro
$nombre = "Lucía";
$apellido = "Ortiz";
$email = "lucia@ejemplo.com";
$stmt->execute();
echo "Registros insertados exitosamente";
} catch (PDOException $e) {
// Mostrar el error si ocurre
echo "Error: " . $e->getMessage();
}
// Cerrar la conexión
$conexion = null;
?>
Explicación del código
prepare(): Prepara la sentencia SQL con marcadores de posición nombrados (:nombre, :apellido, :email).
bindParam(): Vincula los valores a los marcadores de posición.
execute(): Ejecuta la consulta para insertar los valores.
¿Cuál método debería utilizar?
MySQLi:
Ventajas: Es una extensión específica para MySQL, lo que puede ofrecer una ligera mejora en el rendimiento al interactuar exclusivamente con bases de datos MySQL.
Desventajas: Solo funciona con MySQL, lo que limita su flexibilidad si necesitas cambiar a otra base de datos en el futuro.
PDO:
Ventajas: PDO es una extensión más versátil que funciona con múltiples tipos de bases de datos, no solo MySQL. Además, PDO admite transacciones y un manejo de excepciones más robusto.
Desventajas: Si solo vas a trabajar con MySQL, PDO puede ser un poco más complejo de configurar en comparación con MySQLi.
Conclusión
Las sentencias preparadas son una herramienta esencial para cualquier desarrollador PHP que trabaje con bases de datos. No solo mejoran la seguridad al proteger contra inyecciones SQL, sino que también mejoran la eficiencia al reutilizar consultas. Dependiendo de las necesidades de tu proyecto, puedes optar por usar MySQLi o PDO para implementar estas consultas.