certmundo.
es‑mx

7 min de lectura

¿Cómo insertar y leer datos de MySQL con PHP?

Insertar y leer datos de MySQL con PHP se hace con dos comandos SQL: INSERT INTO para guardar información y SELECT para recuperarla.

El momento en que tu aplicación cobra vida

Imagina que lanzas un sitio de registro para empleados de una empresa como Liverpool. Los usuarios llenan el formulario con su nombre y correo. Presionan el botón. Y... no pasa nada. Sin base de datos, tu formulario es solo papel digital. Con INSERT y SELECT, esos datos se guardan y aparecen en pantalla en segundos. Aquí aprendes exactamente cómo lograrlo.

El sistema CRUD-Base: dos comandos para empezar

El desarrollo web gira alrededor de cuatro operaciones: Crear, Leer, Actualizar y Eliminar (CRUD). Antes de dominarlas todas, necesitas las dos más importantes: Crear con INSERT y Leer con SELECT. A este par de operaciones lo llamaremos el sistema CRUD-Base. Es el mínimo viable para cualquier aplicación real.

El flujo siempre es el mismo:

  1. El usuario envía datos desde un formulario HTML.
  2. PHP recibe esos datos y los pasa a una consulta preparada.
  3. MySQL ejecuta la consulta y guarda o devuelve la información.
  4. PHP muestra el resultado en pantalla.

Este flujo no cambia, ya sea que trabajes en una startup o en una empresa como FEMSA.

La tabla que vas a usar

Antes de escribir PHP, necesitas una tabla en MySQL. Usa este código SQL para crearla:

CREATE TABLE usuarios (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nombre VARCHAR(100) NOT NULL,
    correo VARCHAR(150) NOT NULL UNIQUE,
    fecha_registro DATETIME DEFAULT CURRENT_TIMESTAMP
);

Esta tabla guarda cuatro cosas: un ID automático, el nombre, el correo y la fecha de registro. El campo fecha_registro se llena solo. Tú no necesitas enviarlo desde PHP.

Cómo guardar datos con INSERT

El comando INSERT INTO agrega una fila nueva a tu tabla. La estructura básica es:

INSERT INTO tabla (columna1, columna2) VALUES (:valor1, :valor2);

Los dos puntos (:valor1) son marcadores de posición. Como aprendiste en la lección anterior, esto es parte de las consultas preparadas con PDO. Nunca pongas datos del usuario directamente en el SQL.

Aquí está el archivo registrar.php completo:

<?php
require_once 'conexion.php';

$nombre = $_POST['nombre'] ?? '';
$correo = $_POST['correo'] ?? '';

if ($nombre === '' || $correo === '') {
    echo "Todos los campos son obligatorios.";
    exit;
}

$sql = "INSERT INTO usuarios (nombre, correo) VALUES (:nombre, :correo)";
$stmt = $pdo->prepare($sql);

$stmt->execute([
    ':nombre' => $nombre,
    ':correo' => $correo
]);

echo "Usuario registrado correctamente.";
?>

¿Qué hace cada parte?

  • require_once 'conexion.php' trae la conexión PDO que ya configuraste.
  • $_POST['nombre'] ?? '' toma el valor del formulario. Si no existe, usa una cadena vacía.
  • La validación básica evita guardar registros vacíos.
  • prepare() y execute() protegen contra inyección SQL.

El formulario HTML que alimenta el sistema

Necesitas un formulario que envíe datos a registrar.php. Este es el archivo index.html:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Registro de Usuario</title>
</head>
<body>
    <h2>Registro de empleados</h2>
    <form action="registrar.php" method="POST">
        <label>Nombre: <input type="text" name="nombre"></label><br>
        <label>Correo: <input type="email" name="correo"></label><br>
        <button type="submit">Registrar</button>
    </form>
</body>
</html>

El atributo method="POST" envía los datos de forma segura. El action="registrar.php" le dice al navegador a dónde ir cuando el usuario presiona el botón.

Cómo leer datos con SELECT

Guardar datos es solo la mitad del trabajo. También necesitas mostrarlos. El comando SELECT recupera filas de tu tabla.

Este es el archivo lista.php:

<?php
require_once 'conexion.php';

$sql = "SELECT id, nombre, correo, fecha_registro FROM usuarios ORDER BY fecha_registro DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute();

$usuarios = $stmt->fetchAll();
?>

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Lista de Usuarios</title>
</head>
<body>
    <h2>Usuarios registrados</h2>
    <table border="1">
        <tr>
            <th>ID</th>
            <th>Nombre</th>
            <th>Correo</th>
            <th>Fecha</th>
        </tr>
        <?php foreach ($usuarios as $usuario): ?>
        <tr>
            <td><?= htmlspecialchars($usuario['id']) ?></td>
            <td><?= htmlspecialchars($usuario['nombre']) ?></td>
            <td><?= htmlspecialchars($usuario['correo']) ?></td>
            <td><?= htmlspecialchars($usuario['fecha_registro']) ?></td>
        </tr>
        <?php endforeach; ?>
    </table>
</body>
</html>

Tres funciones clave aquí:

  • fetchAll() devuelve todos los resultados como un arreglo de arreglos asociativos.
  • foreach recorre cada fila y la muestra en una tabla HTML.
  • htmlspecialchars() convierte caracteres especiales en HTML seguro. Esto evita ataques XSS.

Aplicación práctica: sistema de empleados de Bimbo

Imagina que eres desarrollador en Bimbo. Tu jefe necesita un sistema interno para registrar empleados nuevos. Cada empleado tiene nombre, correo y salario. Así adaptarías la tabla:

CREATE TABLE empleados (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nombre VARCHAR(100) NOT NULL,
    correo VARCHAR(150) NOT NULL UNIQUE,
    salario DECIMAL(10, 2) NOT NULL,
    fecha_ingreso DATETIME DEFAULT CURRENT_TIMESTAMP
);

Y así insertarías un empleado nuevo con salario de $18,500:

<?php
require_once 'conexion.php';

$nombre  = $_POST['nombre']  ?? '';
$correo  = $_POST['correo']  ?? '';
$salario = $_POST['salario'] ?? 0;

$sql = "INSERT INTO empleados (nombre, correo, salario) VALUES (:nombre, :correo, :salario)";
$stmt = $pdo->prepare($sql);

$stmt->execute([
    ':nombre'  => $nombre,
    ':correo'  => $correo,
    ':salario' => $salario
]);

echo "Empleado registrado con salario de $" . number_format($salario, 0, '.', ',');
?>

La salida en pantalla mostraría: Empleado registrado con salario de $18,500.

Con un simple SELECT puedes listar a todos los empleados con salarios entre $10,000 y $30,000 para filtrar por rango:

$sql = "SELECT nombre, correo, salario FROM empleados WHERE salario BETWEEN :min AND :max ORDER BY salario DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute([':min' => 10000, ':max' => 30000]);
$resultados = $stmt->fetchAll();

Eso mismo lo usaría Mercado Libre para filtrar vendedores por volumen de ventas, o el SAT para clasificar contribuyentes por nivel de ingresos.

Errores comunes y cómo evitarlos

Error 1: Usar query() con datos del usuario

Este código es peligroso:

// MAL: nunca hagas esto
$pdo->query("INSERT INTO usuarios (nombre) VALUES ('$nombre')");

Si $nombre contiene '); DROP TABLE usuarios; --, tu tabla desaparece. Usa siempre prepare() y execute().

Error 2: Olvidar htmlspecialchars() al mostrar datos

Sin esta función, un usuario podría guardar <script>alert('hackeado')</script> como nombre. Eso ejecutaría código JavaScript en el navegador de cualquier persona que vea la lista.

Error 3: No verificar si el INSERT fue exitoso

Puedes usar rowCount() para confirmar que se insertó al menos una fila:

$stmt->execute([':nombre' => $nombre, ':correo' => $correo]);

if ($stmt->rowCount() > 0) {
    echo "Registro exitoso.";
} else {
    echo "No se pudo registrar. Intenta de nuevo.";
}

Error 4: No manejar correos duplicados

Como el campo correo tiene UNIQUE, insertar un correo ya existente lanzará una excepción. Usa un bloque try-catch para manejarlo con elegancia:

try {
    $stmt->execute([':nombre' => $nombre, ':correo' => $correo]);
    echo "Usuario registrado.";
} catch (PDOException $e) {
    if ($e->getCode() === '23000') {
        echo "Este correo ya está registrado.";
    } else {
        echo "Error inesperado. Contacta al administrador.";
    }
}

El código de error 23000 es el estándar SQL para violaciones de unicidad. Este patrón lo usan aplicaciones profesionales en todo México.

Los dos comandos que mueven cualquier aplicación

Con INSERT INTO guardas. Con SELECT recuperas. Todo sistema de registro, catálogo de productos o historial de pedidos usa exactamente estas dos operaciones como base.

El secreto no está en conocer mil comandos SQL, sino en dominar bien estos dos y aplicarlos con consultas preparadas siempre.

Puntos clave

  • Usa `INSERT INTO` con `prepare()` y `execute()` para guardar datos del usuario de forma segura. Nunca construyas el SQL concatenando variables directamente.
  • Usa `SELECT` con `fetchAll()` para recuperar todas las filas y `foreach` para mostrarlas en HTML. Siempre aplica `htmlspecialchars()` al imprimir datos en pantalla.
  • El campo `UNIQUE` en MySQL protege contra correos duplicados, pero lanza una excepción si lo viola. Usa `try-catch` con el código de error `23000` para mostrar un mensaje claro al usuario.
  • Usa `rowCount()` después de un `execute()` para confirmar que el `INSERT` realmente guardó una fila. No asumas que funcionó sin verificarlo.
  • El flujo CRUD-Base (INSERT + SELECT) es la base de cualquier sistema real: formulario HTML → PHP recibe y valida → MySQL guarda o devuelve → PHP muestra el resultado.

Comparte esta lección:

¿Cómo insertar y leer datos de MySQL con PHP? | PHP y MySQL: Desarrollo Web con Base de Datos | Certmundo