Introducción
En esta etapa del curso, entramos en una de las áreas más importantes y prácticas en el desarrollo web con PHP: el manejo de bases de datos. Las bases de datos son el corazón de la mayoría de las aplicaciones. Permiten almacenar, consultar, modificar y eliminar datos de forma persistente, lo cual es fundamental para funcionalidades como registros de usuarios, publicaciones, productos, comentarios, reservas, y mucho más.
PHP se integra de fácilmente con sistemas de gestión de bases de datos como MySQL, uno de los más populares del mundo, especialmente en entornos LAMP (Linux, Apache, MySQL, PHP). En este capítulo aprenderás cómo conectar PHP con una base de datos MySQL, cómo ejecutar consultas y cómo manipular los datos de forma ágil y segura.
Además, abordaremos las dos formas principales de interactuar con bases de datos desde PHP:
- MySQLi (MySQL Improved): una extensión específica para MySQL que permite realizar consultas tanto de forma orientada a objetos como procedimental.
- PDO (PHP Data Objects): una interfaz más flexible y orientada a objetos que permite trabajar con múltiples bases de datos (no solo MySQL), usando una misma sintaxis general.
También hablaremos de uno de los aspectos más críticos en la programación web: la seguridad. Un error común en muchos desarrollos es la exposición a inyecciones SQL, una técnica que puede comprometer totalmente la integridad de la base de datos. Aprenderás cómo evitar este tipo de vulnerabilidades utilizando buenas prácticas como el uso de consultas preparadas. Empecemos…
10.1 Introducción a MySQL y PHP
¿Qué es MySQL?
Como probablemente ya sepas, MySQL es un sistema de gestión de bases de datos relacional (RDBMS) de código abierto y muy popular en el desarrollo de aplicaciones web. Está basado en el lenguaje SQL (Structured Query Language), que permite gestionar bases de datos mediante comandos estructurados para realizar tareas como insertar, consultar, actualizar y eliminar datos.
MySQL organiza los datos de la siguiente manera:
- Bases de datos (colecciones de información relacionada)
- Tablas (estructuras dentro de las bases de datos que contienen filas y columnas)
- Filas o registros (cada fila es una entrada específica)
- Columnas o campos (cada columna representa un tipo de dato específico, como nombre, edad, email, etc.)
Ejemplo de tabla en MySQL:
id | nombre | correo |
---|---|---|
1 | Laura | laura@email.com |
2 | Andrés | andres@example.net |
¿Qué papel juega PHP en todo esto?
PHP puede interactuar con MySQL para consultar y modificar datos desde una aplicación web. Esto se hace mediante funciones o clases específicas que permiten conectarse a la base de datos y ejecutar sentencias SQL desde scripts PHP.
Por ejemplo, puedes crear una página que muestre una lista de usuarios que se encuentran en una base de datos, o un formulario que guarde nuevos registros en una tabla.
Requisitos técnicos
Para trabajar con PHP y MySQL necesitas tener un entorno que incluya:
- PHP instalado
- Servidor web Apache (u otro)
- MySQL Server (la base de datos)
- Un entorno como XAMPP, MAMP, LAMP o WAMP ya incluye todo esto.
Esto ya lo vimos en el capítulo 1. Introducción a PHP
Cómo funciona la interacción
El flujo básico de trabajo entre PHP y MySQL es el siguiente:
- El usuario interactúa con una página web (por ejemplo, envía un formulario).
- PHP recibe la solicitud.
- PHP se conecta a la base de datos.
- PHP ejecuta una consulta SQL (por ejemplo, guardar los datos del formulario).
- MySQL devuelve una respuesta.
- PHP interpreta los resultados y genera HTML dinámico como respuesta al usuario.
Crear una base de datos y una tabla (desde PHPMyAdmin o SQL puro)
PhpMyAdmin es un gestor de BBDD gratuito para MySQL muy popular que facilita la labor de mantenimiento de BBDD MySql. Te facilito el link para que puedas descargarlo e instalarlo (https://www.phpmyadmin.net/).
Primero, creamos la base de datos y tabla en phpMyAdmin o desde una consola SQL.
CREATE DATABASE tienda;
USE tienda;
CREATE TABLE productos (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(100),
precio DECIMAL(10,2)
);
10.2 Operaciones CRUD con PDO y MySQLi
CRUD es un acrónimo que representa las cuatro operaciones básicas que se pueden realizar sobre los datos de una base de datos: Crear (Create), Leer (Read), Actualizar (Update) y Eliminar (Delete). Estas operaciones son fundamentales en el desarrollo de aplicaciones web que interactúan con BBDD. Vamos a ver como PHP implementa estas consultas SQL con las extensiones MySQLi y PDO.
Conexión a la base de datos desde PHP
Hay dos formas comunes de conectarse a MySQL desde PHP:
– Conexión con MySQLi
MySQLi significa MySQL Improved («MySQL Mejorado») y es una extensión de PHP que permite interactuar con bases de datos MySQL. Fue introducida como una mejora de la antigua extensión mysql
, que está obsoleta y ya no se debe usar.
¿Por qué se llama «Mejorado»?
Porque incluye características modernas como:
- Soporte para programación orientada a objetos.
- Uso de sentencias preparadas (más seguras contra ataques de inyección SQL).
- Mejor rendimiento y soporte para las funcionalidades más recientes de MySQL.
- Soporte para conexiones persistentes y múltiples consultas.
¿Cómo se usa?
Puedes usar MySQLi de dos formas:
- Estilo orientado a objetos:
$conexion = new mysqli("localhost", "usuario", "contraseña", "base_de_datos");
- Estilo procedural (más clásico):
$conexion = mysqli_connect("localhost", "usuario", "contraseña", "base_de_datos");
Ambas formas funcionan, pero se recomienda el estilo orientado a objetos porque permite un código más limpio y organizado.
Seguridad
Una de las principales ventajas de MySQLi es su compatibilidad con sentencias preparadas, que permiten separar el código SQL de los datos, reduciendo enormemente el riesgo de inyecciones SQL.
Una vez visto cómo se utiliza MySQLi, vamos a conectarnos a la BBDD de Tienda que hemos creado. Utilizaremos el modo orientado a objetos.
<?php
$conexion = new mysqli("localhost", "root", "mypass", "tienda");
if ($conexion->connect_error) {
die("Error en la conexión: " . $conexion->connect_error);
} else {
echo "Conexión exitosa con MySQLi";
}
?>
En este ejemplo vemos que:
"localhost"
es el servidor donde se ejecuta MySQL (normalmente en tu propia máquina)."root"
es el usuario por defecto."mypass"
es la contraseña para conectarse a la BBDD."tienda"
es la base de datos a la que queremos acceder.
Conexión con PDO (PHP Data Objects)
¿Qué es PDO?
PDO (siglas de PHP Data Objects) es una interfaz de acceso a bases de datos en PHP que permite conectarse y trabajar con múltiples motores de bases de datos, no solo con MySQL, sino también con PostgreSQL, SQLite, SQL Server, Oracle, entre otros.
Es decir, PDO es una capa de abstracción que te permite escribir código que puede funcionar con distintas bases de datos sin tener que reescribirlo todo si decides cambiar de sistema de gestión (por ejemplo, de MySQL a PostgreSQL).
¿Qué ventajas tiene usar PDO?
- Compatible con múltiples motores de bases de datos.
- Usa siempre programación orientada a objetos.
- Soporte nativo para sentencias preparadas, lo que ayuda a prevenir ataques de inyección SQL.
- Código más limpio y reutilizable.
- Posibilidad de trabajar con transacciones, ideal para operaciones críticas.
Ejemplo básico de conexión con PDO
<?php
try {
$pdo = new PDO("mysql:host=localhost;dbname=mi_base_de_datos", "usuario", "contraseña");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Conexión exitosa";
} catch (PDOException $e) {
echo "Error en la conexión: " . $e->getMessage();
}
?>
¿Qué es setAttribute()
en PDO?
Te abrás fijado en el ejemplo hacemos uso de setAttribute(
). Este es un método del objeto PDO que permite configurar el comportamiento de la conexión a la base de datos. Sirve para ajustar diferentes parámetros para manejar errores, cómo se obtienen los resultados, si se usan conexiones persistentes, etc.
Controlar aspectos clave de la conexión y de las operaciones con bases de datos mejora la seguridad, eficiencia y control del código.
Tabla de atributos comunes de setAttribute()
en PDO
Atributo (PDO::CONSTANTE ) | ¿Qué hace? | Opciones posibles |
---|---|---|
PDO::ATTR_ERRMODE | Define el modo de manejo de errores de PDO. | – PDO::ERRMODE_SILENT (por defecto)– PDO::ERRMODE_WARNING – PDO::ERRMODE_EXCEPTION |
PDO::ATTR_DEFAULT_FETCH_MODE | Determina el formato de los resultados de las consultas (fetch , fetchAll , etc.). | – PDO::FETCH_ASSOC – PDO::FETCH_NUM – PDO::FETCH_BOTH – PDO::FETCH_OBJ , etc. |
PDO::ATTR_PERSISTENT | Usa una conexión persistente, que se mantiene abierta entre peticiones. | – true (activar)– false (desactivar) |
PDO::ATTR_EMULATE_PREPARES | Controla si PDO debe emular consultas preparadas (por software) o usarlas nativamente. | – true (emula)– false (usa consultas preparadas del servidor, más seguro) |
PDO::MYSQL_ATTR_INIT_COMMAND | Ejecuta un comando SQL inicial al conectarse (sólo para MySQL). | – Una cadena SQL, por ejemplo: "SET NAMES utf8" |
PDO::ATTR_CASE | Controla cómo se devuelven los nombres de las columnas. | – PDO::CASE_LOWER – PDO::CASE_UPPER – PDO::CASE_NATURAL |
PDO::ATTR_AUTOCOMMIT | Define si las operaciones se confirman automáticamente. | – true (activar)– false (manual, requiere commit() ) |
PDO::ATTR_TIMEOUT | Tiempo de espera en segundos para la conexión. | – Número entero, por ejemplo 5 |
Ejemplo de uso
<?php
$pdo = new PDO("mysql:host=localhost;dbname=mi_base", "usuario", "clave");
// Configuraciones recomendadas
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Manejo de errores con excepciones
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); // Resultados como arrays asociativos
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); // Consultas preparadas reales
Como recomendación, siempre deberías configurar al menos los siguientes parámetros:
ATTR_ERRMODE
comoERRMODE_EXCEPTION
ATTR_DEFAULT_FETCH_MODE
comoFETCH_ASSOC
ATTR_EMULATE_PREPARES
comofalse
(para mayor seguridad)
Sentencias preparadas con PDO
Las sentencias preparadas (o prepared statements) en PDO son una funcionalidad que permite preparar una consulta SQL una vez y ejecutarla múltiples veces con diferentes valores.
Este tipo de sentencias ayudan principalmente a:
- Evitar inyecciones SQL (lo más importante).
- Mejorar el rendimiento si ejecutas una misma consulta muchas veces con distintos datos.
- Hacer que el código sea más legible y organizado.
¿Cómo funcionan?
Las sentencias preparadas funcionan en dos fases:
- Preparación de la consulta: el servidor de base de datos analiza y compila la consulta con marcadores (
?
o:nombre
), pero sin valores todavía. - Ejecución: se le pasan los valores reales para los marcadores, y se ejecuta la consulta.
Tipos de marcadores
PDO permite dos tipos de marcadores en las sentencias preparadas:
Tipo de marcador | Ejemplo | Características |
---|---|---|
Posicional | ? | Más simple. Los valores deben pasarse en el orden correcto. |
Nombrado | :nombre , :email | Más legible. Puedes asociar cada valor con su marcador por nombre. |
Ejemplo 1: Sentencia preparada con marcadores posicionados
<?php
$pdo = new PDO("mysql:host=localhost;dbname=mi_base", "usuario", "clave");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT * FROM usuarios WHERE email = ? AND activo = ?";
$stmt = $pdo->prepare($sql); // Preparar
// Ejecutar con valores
$stmt->execute(["usuario@correo.com", 1]);
// Obtener resultados
$resultado = $stmt->fetchAll();
print_r($resultado);
Ejemplo 2: Sentencia preparada con marcadores nombrados
<?php
$sql = "INSERT INTO usuarios (nombre, email) VALUES (:nombre, :email)";
$stmt = $pdo->prepare($sql);
// Asignamos los valores como array asociativo
$stmt->execute([
':nombre' => 'Ana',
':email' => 'ana@example.com'
]);
Este método es más claro y mantenible, especialmente si hay muchos parámetros.
Ventajas de las sentencias preparadas
Ventaja | Explicación |
---|---|
Seguridad | Evitan inyecciones SQL al separar el código SQL de los datos del usuario. |
Eficiencia | Puedes ejecutar muchas veces la misma consulta sin reanalizarla. |
Claridad | Separan la lógica SQL de los valores, facilitando la lectura del código. |
¿Por qué son más seguras?
Las sentencias preparadas son seguras proque previenen ataques como la inyección SQL. Esto lo veremos más endetalle en el apartado siguiente.
¿Cuándo usarlas?
Siempre que recibas datos externos (formularios, URLs, cookies, etc.) que se usen en consultas SQL, debes usar sentencias preparadas.
<?php
$stmt = $pdo->prepare("SELECT * FROM usuarios WHERE email = :email");
$stmt->execute(['email' => 'ejemplo@correo.com']);
$resultados = $stmt->fetchAll();
Con las sentencias preparadas, separas la lógica SQL de los datos que ingresan los usuarios, y así evitas que un atacante pueda inyectar código malicioso.
¿Cuándo usar PDO y cuándo MySQLi?
- Si solo trabajas con MySQL y prefieres tener acceso a funciones específicas de ese motor, MySQLi es una buena opción.
- Si quieres portabilidad y un código más limpio y flexible, o si piensas trabajar con diferentes tipos de bases de datos, PDO es la opción ideal.
Volviendo a nuestro ejemplo de la tienda, tenemos que para hacer la conexión con PDO se haría de la siguiente forma:
<?php
try {
$conexion = new PDO("mysql:host=localhost;dbname=tienda", "root", "mypass");
$conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Conexión exitosa con PDO";
} catch (PDOException $e) {
echo "Error de conexión: " . $e->getMessage();
}
?>
Visto como nos conectamos a las BBDD con MySQLi y con PDO, vamos a ver los distintos casos de consultas que podemos lanzar.
Insertar datos en la tabla desde PHP
Con MySQLi:
<?php
$conexion = new mysqli("localhost", "root", "mypass", "tienda");
$conexion->query("INSERT INTO productos (nombre, precio) VALUES ('Camiseta', 19.99)");
?>
Con PDO:
<?php
$conexion = new PDO("mysql:host=localhost;dbname=tienda", "root", "mypass");
$conexion->exec("INSERT INTO productos (nombre, precio) VALUES ('Pantalón', 29.99)");
?>
Mostrar los datos almacenados (consulta SELECT)
MySQLi:
<?php
$conexion = new mysqli("localhost", "root", "mypass", "tienda");
$resultado = $conexion->query("SELECT * FROM productos");
while ($fila = $resultado->fetch_assoc()) {
echo "Producto: " . $fila['nombre'] . " - Precio: " . $fila['precio'] . "<br>";
}
?>
PDO:
<?php
$conexion = new PDO("mysql:host=localhost;dbname=tienda", "root", "mypass");
$consulta = $conexion->query("SELECT * FROM productos");
while ($fila = $consulta->fetch(PDO::FETCH_ASSOC)) {
echo "Producto: " . $fila['nombre'] . " - Precio: " . $fila['precio'] . "<br>";
}
?>
Actualizar los datos almacenados (consulta UPDATE)
MySQLi:
<?php
$conexion = new mysqli("localhost", "root", "mypass", "tienda");
// Comprobamos conexión
if ($conexion->connect_error) {
die("Conexión fallida: " . $conexion->connect_error);
}
// Actualizamos el precio
$sql = "UPDATE productos SET precio = 299.99 WHERE nombre = 'Monitor'";
if ($conexion->query($sql) === TRUE) {
echo "Producto actualizado correctamente.";
} else {
echo "Error al actualizar: " . $conexion->error;
}
$conexion->close();
?>
PDO:
<?php
try {
$conexion = new PDO("mysql:host=localhost;dbname=tienda", "root", "mypass");
$conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Usamos sentencia preparada
$sql = "UPDATE productos SET precio = :precio WHERE nombre = :nombre";
$stmt = $conexion->prepare($sql);
$stmt->execute([
':precio' => 299.99,
':nombre' => 'Monitor'
]);
echo "Producto actualizado correctamente.";
} catch (PDOException $e) {
echo "Error al actualizar: " . $e->getMessage();
}
?>
Borrar los datos almacenados (consulta DELETE)
MySQLi:
<?php
$conexion = new mysqli("localhost", "root", "mypass", "tienda");
if ($conexion->connect_error) {
die("Conexión fallida: " . $conexion->connect_error);
}
$sql = "DELETE FROM productos WHERE nombre = 'Teclado'";
if ($conexion->query($sql) === TRUE) {
echo "Producto eliminado correctamente.";
} else {
echo "Error al eliminar: " . $conexion->error;
}
$conexion->close();
?>
PDO:
<?php
try {
$conexion = new PDO("mysql:host=localhost;dbname=tienda", "root", "mypass");
$conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "DELETE FROM productos WHERE nombre = :nombre";
$stmt = $conexion->prepare($sql);
$stmt->execute([':nombre' => 'Teclado']);
echo "Producto eliminado correctamente.";
} catch (PDOException $e) {
echo "Error al eliminar: " . $e->getMessage();
}
?>
10.3 Prevención de Inyección SQL
¿Qué es una inyección SQL?
La inyección SQL es una de las vulnerabilidades más comunes y peligrosas en aplicaciones web que interactúan con bases de datos. Se produce cuando un usuario malintencionado manipula el contenido de una entrada (por ejemplo, un formulario) para alterar la consulta SQL ejecutada por el servidor. Esta alteración puede permitir:
- Acceder a información sensible (como contraseñas o datos personales).
- Modificar o eliminar registros de la base de datos.
- Ejecutar comandos administrativos sobre la base de datos.
- En casos graves, tomar el control del servidor.
Ejemplo clásico de inyección:
Supongamos que tenemos el siguiente código (inseguro):
<?php
$usuario = $_POST['usuario'];
$contrasena = $_POST['contrasena'];
$conexion = new mysqli("localhost", "root", "", "tienda");
$sql = "SELECT * FROM usuarios WHERE nombre = '$usuario' AND contrasena = '$contrasena'";
$resultado = $conexion->query($sql);
?>
Un atacante podría introducir en el campo usuario
del formulario de la página web el siguiente texto:
' OR '1'='1
Entonces la consulta quedaría así:
SELECT * FROM usuarios WHERE nombre = '' OR '1'='1' AND contrasena = ''
Esa condición siempre se cumple ('1'='1'
es siempre verdadera), por lo que el atacante podría entrar sin necesidad de saber una contraseña válida.
¿Cómo prevenir la inyección SQL?
La mejor forma de prevenirla es NO concatenar directamente los datos de entrada del usuario en las consultas SQL. En su lugar, se deben utilizar sentencias preparadas con consultas parametrizadas, que separan los datos de la lógica SQL.
Esto se puede hacer fácilmente con PDO y MySQLi, y evita que el contenido de las variables se interprete como parte del código SQL.
Prevención con PDO (Preparadas + Parámetros)
<?php
$usuario = $_POST['usuario'];
$contrasena = $_POST['contrasena'];
$pdo = new PDO("mysql:host=localhost;dbname=tienda", "root", "");
$consulta = $pdo->prepare("SELECT * FROM usuarios WHERE nombre = :nombre AND contrasena = :contrasena");
$consulta->bindParam(':nombre', $usuario);
$consulta->bindParam(':contrasena', $contrasena);
$consulta->execute();
$resultado = $consulta->fetchAll();
if ($resultado) {
echo "Bienvenido, $usuario";
} else {
echo "Credenciales incorrectas";
}
?>
En este ejemplo:
prepare()
crea la consulta sin ejecutarla.:nombre
y:contrasena
son marcadores de parámetros.bindParam()
une esos marcadores a valores concretos sin permitir inyección.- Luego se ejecuta la consulta con seguridad.
Prevención con MySQLi (Estilo orientado a objetos)
<?php
$conexion = new mysqli("localhost", "root", "", "tienda");
$usuario = $_POST['usuario'];
$contrasena = $_POST['contrasena'];
$stmt = $conexion->prepare("SELECT * FROM usuarios WHERE nombre = ? AND contrasena = ?");
$stmt->bind_param("ss", $usuario, $contrasena);
$stmt->execute();
$resultado = $stmt->get_result();
if ($resultado->num_rows > 0) {
echo "Bienvenido, $usuario";
} else {
echo "Usuario o contraseña incorrectos";
}
?>
Aquí:
?
son marcadores posicionales para parámetros.bind_param()
se encarga de pasar los valores sin riesgo."ss"
indica que se pasan dos cadenas de texto (string, string).
Otras buenas prácticas para proteger tu aplicación contra inyecciones SQL
- Validar y sanear entradas: aunque uses sentencias preparadas, es buena idea validar que el dato tenga el formato esperado (por ejemplo, que un ID sea numérico).
- Limitar privilegios del usuario de base de datos: el usuario con el que se conecta tu aplicación no debería tener más permisos de los necesarios.
- Evitar mostrar errores SQL en producción: nunca muestres mensajes de error de SQL directamente en la web, ya que pueden dar pistas a un atacante.
- Utilizar contraseñas cifradas: incluso aunque haya una inyección, nunca deben guardarse contraseñas como texto plano.
En definitiva, la inyección SQL es un riesgo serio que puede comprometer por completo la seguridad de una aplicación. Afortunadamente, prevenirla es relativamente fácil utilizando las herramientas adecuadas que nos da PHP, como sentencias preparadas con PDO o MySQLi. Siempre debes tratar las entradas del usuario con desconfianza y evitar insertar directamente esos datos en consultas SQL sin protegerlas.
Resumiendo.
En este capítulo aprendimos a conectar nuestras aplicaciones PHP con bases de datos MySQL, una de las tareas más comunes y fundamentales en el desarrollo web. Comenzamos con una introducción al sistema de gestión de bases de datos MySQL y vimos cómo PHP puede interactuar con él a través de dos extensiones principales: MySQLi y PDO.
Estudiamos cómo establecer conexiones con ambas tecnologías, destacando las diferencias entre ellas, y exploramos los métodos disponibles para realizar operaciones básicas CRUD: crear, leer, actualizar y eliminar registros desde una base de datos.
Nos centramos en PDO por su flexibilidad y capacidad para trabajar con múltiples motores de bases de datos, y profundizamos en detalles como el uso de setAttribute()
para personalizar el comportamiento de la conexión. También aprendimos a utilizar sentencias preparadas, una técnica fundamental para escribir consultas seguras y eficientes, que además protege contra la inyección SQL, uno de los ataques más peligrosos y frecuentes en el desarrollo web.
Concluimos el capítulo viendo buenas prácticas de seguridad, validación y manejo de errores, con el objetivo de desarrollar aplicaciones robustas, funcionales y seguras.
Vamos ahora con unos ejercicios prácticos propuestos.
Ejercicio 1: Mostrar productos desde la base de datos
Enunciado:
Crea una página PHP que se conecte a una base de datos llamada tienda
y muestre en pantalla una lista de todos los productos con su nombre y precio. Usa PDO para conectarte y obtener los datos.
Enunciado:
Crea una página PHP que se conecte a una base de datos llamada
tienda
y muestre en pantalla una lista de todos los productos con su nombre y precio. Usa PDO para conectarte y obtener los datos.Código:
<?php
try {
$conexion = new PDO("mysql:host=localhost;dbname=tienda", "root", "mypass");
$conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$consulta = $conexion->query("SELECT nombre, precio FROM productos");
echo "<h2>Lista de Productos</h2>";
while ($producto = $consulta->fetch(PDO::FETCH_ASSOC)) {
echo "Nombre: " . $producto['nombre'] . " - Precio: " . $producto['precio'] . " €<br>";
}
} catch (PDOException $e) {
echo "Error en la conexión: " . $e->getMessage();
}
?>
Explicación:
- Se establece la conexión usando PDO y se configura el modo de error con
setAttribute
. - Se realiza una consulta simple con
query()
y se recorren los resultados confetch()
. - Se muestra el nombre y precio de cada producto.
Ejercicio 2: Insertar un nuevo producto mediante formulario
Enunciado:
Crea un formulario HTML que permita introducir un nuevo producto (nombre y precio). Al enviarlo, el script PHP debe insertar el producto en la base de datos tienda
, tabla productos
, usando sentencias preparadas con PDO.
Enunciado:
Crea un formulario HTML que permita introducir un nuevo producto (nombre y precio). Al enviarlo, el script PHP debe insertar el producto en la base de datos
tienda
, tabla productos
, usando sentencias preparadas con PDO.Código:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
$conexion = new PDO("mysql:host=localhost;dbname=tienda", "root", "mypass");
$conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$nombre = $_POST['nombre'];
$precio = $_POST['precio'];
$sql = "INSERT INTO productos (nombre, precio) VALUES (:nombre, :precio)";
$stmt = $conexion->prepare($sql);
$stmt->bindParam(':nombre', $nombre);
$stmt->bindParam(':precio', $precio);
$stmt->execute();
echo "Producto insertado correctamente.";
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
}
?>
<form method="POST">
Nombre del producto: <input type="text" name="nombre" required><br>
Precio: <input type="number" name="precio" step="0.01" required><br>
<input type="submit" value="Agregar Producto">
</form>
Explicación:
- El formulario recopila nombre y precio.
- Al enviarse, se conecta a la base de datos y se usa una sentencia preparada (
prepare
) para insertar los datos. - Se usan
bindParam()
para enlazar los valores de forma segura, evitando inyecciones SQL.
Ejercicio 3: Actualizar el precio de un producto
Enunciado:
Modifica el precio de un producto existente en la base de datos. El usuario deberá introducir el id
del producto y el nuevo precio. El cambio se realizará con una sentencia preparada de PDO.
Enunciado:
Modifica el precio de un producto existente en la base de datos. El usuario deberá introducir el
id
del producto y el nuevo precio. El cambio se realizará con una sentencia preparada de PDO.Código:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
$conexion = new PDO("mysql:host=localhost;dbname=tienda", "root", "mypass");
$conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$id = $_POST['id'];
$nuevoPrecio = $_POST['precio'];
$sql = "UPDATE productos SET precio = :precio WHERE id = :id";
$stmt = $conexion->prepare($sql);
$stmt->bindParam(':precio', $nuevoPrecio);
$stmt->bindParam(':id', $id);
$stmt->execute();
echo "Producto actualizado correctamente.";
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
}
?>
<form method="POST">
ID del producto a actualizar: <input type="number" name="id" required><br>
Nuevo precio: <input type="number" name="precio" step="0.01" required><br>
<input type="submit" value="Actualizar">
</form>
Explicación:
- El formulario solicita el ID del producto y el nuevo precio.
- El script usa
UPDATE
con sentencia preparada, protegiendo la consulta de manipulaciones externas. - Los valores se vinculan con
bindParam
y la sentencia se ejecuta conexecute()
.
Bibliografía de programación en PHP.
- Aprende PHP desde Cero: Todo lo que necesitas para programar en PHP. Autor: Gerardo G. Urtiaga (Editorial: Editorior Independiente)
- PHP y MySQL: Domine el desarrollo de un sitio web dinámico e interactivo. Autor: Olivier Heurtel (Editorial: Ediciones ENI)
- PHP 8: Programación de aplicaciones web en el servidor: Guía paso a paso con ejemplos y proyectos prácticos. Autor: Jose Vicente Cerratlá.