Lección 15: CRUD
La palabra CRUD vas a leerla mucho en el mundillo de la programación. Son unas simples siglas:
- Create -> Crear
- Read -> Leer
- Update -> Actualizar
- Delete -> Borrar
O lo que es lo mismo, gestionar una tabla de una base de datos con las operaciones mínimas.

Preparando la base de datos
Antes de ponernos a realizar nuestras consultas necesitaremos datos. Ejecuta con el siguiente código SQL para tener una pequeña lista de libros. Creará una base de datos, una tabla y algunas filas de ejemplo.
CREATE DATABASE ejemplo DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
USE ejemplo;
CREATE TABLE IF NOT EXISTS libros (
codigo INT AUTO_INCREMENT,
titulo VARCHAR(255) NOT NULL,
autor VARCHAR(255) NOT NULL,
disponible TINYINT NOT NULL,
PRIMARY KEY (codigo)
) ENGINE=INNODB;
INSERT INTO libros VALUES ('', 'La Guerra y la Paz', 'León Tolstoi', TRUE);
INSERT INTO libros VALUES ('', 'Las Aventuras de Huckleberry Finn', 'Mark Twain', FALSE);
INSERT INTO libros VALUES ('', 'Hamlet', 'William Shakespeare', TRUE);
INSERT INTO libros VALUES ('', 'En busca del tiempo perdido', 'Marcel Proust', FALSE);
INSERT INTO libros VALUES ('', 'Don Quijote de la Mancha', 'Miguel de Cervantes', TRUE);
Leyendo datos
Nuestro código PHP hará una sencilla consulta a la base de datos.
// Variables
$hostDB = '127.0.0.1';
$nombreDB = 'ejemplo';
$usuarioDB = 'root';
$contrasenyaDB = '';
// Conecta con base de datos
$hostPDO = "mysql:host=$hostDB;dbname=$nombreDB;";
$miPDO = new PDO($hostPDO, $usuarioDB, $contrasenyaDB);
// Prepara SELECT
$miConsulta = $miPDO->prepare('SELECT * FROM libros;');
// Ejecuta consulta
$miConsulta->execute();
Y a continuación se iterará con un foreach cada fila en una tabla.
<table>
<tr>
<th>Código</th>
<th>Título</th>
<th>Autor</th>
<th>¿Disponible?</th>
</tr>
<?php foreach ($miConsulta as $clave => $valor): ?>
<tr>
<td><?= $valor['codigo']; ?></td>
<td><?= $valor['titulo']; ?></td>
<td><?= $valor['autor']; ?></td>
<td><?= $valor['disponible'] ? 'Si' : 'No'; ?></td>
</tr>
<?php endforeach; ?>
</table>
Todo el código unido quedaría de la siguiente forma.
<?php
// Variables
$hostDB = '127.0.0.1';
$nombreDB = 'ejemplo';
$usuarioDB = 'root';
$contrasenyaDB = '';
// Conecta con base de datos
$hostPDO = "mysql:host=$hostDB;dbname=$nombreDB;";
$miPDO = new PDO($hostPDO, $usuarioDB, $contrasenyaDB);
// Prepara SELECT
$miConsulta = $miPDO->prepare('SELECT * FROM libros;');
// Ejecuta consulta
$miConsulta->execute();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Leer - CRUD PHP</title>
<style>
table {
border-collapse: collapse;
width: 100%;
}
table td {
border: 1px solid orange;
text-align: center;
padding: 1.3rem;
}
.button {
border-radius: .5rem;
color: white;
background-color: orange;
padding: 1rem;
text-decoration: none;
}
</style>
</head>
<body>
<p><a class="button" href="nuevo.php">Crear</a></p>
<table>
<tr>
<th>Código</th>
<th>Título</th>
<th>Autor</th>
<th>¿Disponible?</th>
<td></td>
<td></td>
</tr>
<?php foreach ($miConsulta as $clave => $valor): ?>
<tr>
<td><?= $valor['codigo']; ?></td>
<td><?= $valor['titulo']; ?></td>
<td><?= $valor['autor']; ?></td>
<td><?= $valor['disponible'] ? 'Si' : 'No'; ?></td>
<!-- Se utilizará más adelante para indicar si se quiere modificar o eliminar el registro -->
<td><a class="button" href="modificar.php?codigo=<?= $valor['codigo'] ?>">Modificar</a></td>
<td><a class="button" href="borrar.php?codigo=<?= $valor['codigo'] ?>">Borrar</a></td>
</tr>
<?php endforeach; ?>
</table>
</body>
</html>
Si vas a leer un solo registro puedes usar $registro = $miConsulta->fetch();.
¿Has intentado realizar varias foreach con la misma consulta? No es posible ya que el puntero se queda al final de la lista. Un truco es usar $registros = $miConsulta->fetchAll(). Te quedarás con un array que serás capaz de leer todas las veces que necesites.
Crear nuevo registro
Montamos un pequeño formulario donde se pida: título, autor y disponibilidad.
<form method="post">
<p>
<label for="titulo">Titulo</label>
<input id="titulo" type="text" name="titulo">
</p>
<p>
<label for="autor">Autor</label>
<input id="autor" type="text" name="autor">
</p>
<p>
<div>¿Disponible?</div>
<input id="si-disponible" type="radio" name="disponible" value="1" checked> <label for="si-disponible">Si</label>
<input id="no-disponible" type="radio" name="disponible" value="0"> <label for="no-disponible">No</label>
</p>
<p>
<input type="submit" value="Guardar">
</p>
</form>
Después, en el mismo fichero, le decimos que si recibimos un método POST lo guarde en la base de datos con un INSERT.
// Comprobamso si recibimos datos por POST
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Recogemos variables
$titulo = isset($_REQUEST['titulo']) ? $_REQUEST['titulo'] : null;
$autor = isset($_REQUEST['autor']) ? $_REQUEST['autor'] : null;
$disponible = isset($_REQUEST['disponible']) ? $_REQUEST['disponible'] : null;
// Variables
$hostDB = '127.0.0.1';
$nombreDB = 'ejemplo';
$usuarioDB = 'root';
$contrasenyaDB = '';
// Conecta con base de datos
$hostPDO = "mysql:host=$hostDB;dbname=$nombreDB;";
$miPDO = new PDO($hostPDO, $usuarioDB, $contrasenyaDB);
// Prepara INSERT
$miInsert = $miPDO->prepare('INSERT INTO libros (titulo, autor, disponible) VALUES (:titulo, :autor, :disponible)');
// Ejecuta INSERT con los datos
$miInsert->execute(
array(
'titulo' => $titulo,
'autor' => $autor,
'disponible' => $disponible
)
);
// Redireccionamos a Leer
header('Location: leer.php');
}
Todo unido se mostraría de la siguiente manera.
<?php
// Comprobamso si recibimos datos por POST
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Recogemos variables
$titulo = isset($_REQUEST['titulo']) ? $_REQUEST['titulo'] : null;
$autor = isset($_REQUEST['autor']) ? $_REQUEST['autor'] : null;
$disponible = isset($_REQUEST['disponible']) ? $_REQUEST['disponible'] : null;
// Variables
$hostDB = '127.0.0.1';
$nombreDB = 'ejemplo';
$usuarioDB = 'root';
$contrasenyaDB = '';
// Conecta con base de datos
$hostPDO = "mysql:host=$hostDB;dbname=$nombreDB;";
$miPDO = new PDO($hostPDO, $usuarioDB, $contrasenyaDB);
// Prepara INSERT
$miInsert = $miPDO->prepare('INSERT INTO libros (titulo, autor, disponible) VALUES (:titulo, :autor, :disponible)');
// Ejecuta INSERT con los datos
$miInsert->execute(
array(
'titulo' => $titulo,
'autor' => $autor,
'disponible' => $disponible
)
);
// Redireccionamos a Leer
header('Location: leer.php');
}
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Crear - CRUD PHP</title>
</head>
<body>
<form action="" method="post">
<p>
<label for="titulo">Titulo</label>
<input id="titulo" type="text" name="titulo">
</p>
<p>
<label for="autor">Autor</label>
<input id="autor" type="text" name="autor">
</p>
<p>
<div>¿Disponible?</div>
<input id="si-disponible" type="radio" name="disponible" value="1" checked> <label for="si-disponible">Si</label>
<input id="no-disponible" type="radio" name="disponible" value="0"> <label for="no-disponible">No</label>
</p>
<p>
<input type="submit" value="Guardar">
</p>
</form>
</body>
</html>
Modificar
Nuestro código debe realizar dos acciones: conseguir el código del libro a modificar y sobrescribir los datos. Al entrar la página lo haremos con ruta similar a esta:
modificar.php?codigo=3
Para capturar este dato lo hacemos como cualquier otra variables.
$codigo = isset($_REQUEST['codigo']) ? $_REQUEST['codigo'] : null;
Nuestro código PHP quedaría de la siguiente manera.
// Variables
$hostDB = '127.0.0.1';
$nombreDB = 'ejemplo';
$usuarioDB = 'root';
$contrasenyaDB = '';
$codigo = isset($_REQUEST['codigo']) ? $_REQUEST['codigo'] : null;
$titulo = isset($_REQUEST['titulo']) ? $_REQUEST['titulo'] : null;
$autor = isset($_REQUEST['autor']) ? $_REQUEST['autor'] : null;
$disponible = isset($_REQUEST['disponible']) ? $_REQUEST['disponible'] : null;
// Conecta con base de datos
$hostPDO = "mysql:host=$hostDB;dbname=$nombreDB;";
$miPDO = new PDO($hostPDO, $usuarioDB, $contrasenyaDB);
// Comprobamso si recibimos datos por POST
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Prepara UPDATE
$miUpdate = $miPDO->prepare('UPDATE libros SET titulo = :titulo, autor = :autor, disponible = :disponible WHERE codigo = :codigo');
// Ejecuta UPDATE con los datos
$miUpdate->execute(
[
'codigo' => $codigo,
'titulo' => $titulo,
'autor' => $autor,
'disponible' => $disponible
]
);
// Redireccionamos a Leer
header('Location: leer.php');
} else {
// Prepara SELECT
$miConsulta = $miPDO->prepare('SELECT * FROM libros WHERE codigo = :codigo;');
// Ejecuta consulta
$miConsulta->execute(
[
codigo => $codigo
]
);
}
// Obtiene un solo resultado
$libro = $miConsulta->fetch();
Mientras que nuestro HTML será similar al fomulario de creación salvo que necesitaremos rellenar los value.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Crear - CRUD PHP</title>
</head>
<body>
<form method="post">
<p>
<label for="titulo">Titulo</label>
<input id="titulo" type="text" name="titulo" value="<?= $libro['titulo'] ?>">
</p>
<p>
<label for="autor">Autor</label>
<input id="autor" type="text" name="autor" value="<?= $libro['autor'] ?>">
</p>
<p>
<div>¿Disponible?</div>
<input id="si-disponible" type="radio" name="disponible" value="1"<?= $libro['disponible'] ? ' checked' : '' ?>> <label for="si-disponible">Si</label>
<input id="no-disponible" type="radio" name="disponible" value="0"<?= !$libro['disponible'] ? ' checked' : '' ?>> <label for="no-disponible">No</label>
</p>
<p>
<input type="hidden" name="codigo" value="<?= $codigo ?>">
<input type="submit" value="Modificar">
</p>
</form>
</body>
</html>
Todo unido se nos compactaría tal que así.
<?php
// Variables
$hostDB = '127.0.0.1';
$nombreDB = 'ejemplo';
$usuarioDB = 'root';
$contrasenyaDB = '';
$codigo = isset($_REQUEST['codigo']) ? $_REQUEST['codigo'] : null;
$titulo = isset($_REQUEST['titulo']) ? $_REQUEST['titulo'] : null;
$autor = isset($_REQUEST['autor']) ? $_REQUEST['autor'] : null;
$disponible = isset($_REQUEST['disponible']) ? $_REQUEST['disponible'] : null;
// Conecta con base de datos
$hostPDO = "mysql:host=$hostDB;dbname=$nombreDB;";
$miPDO = new PDO($hostPDO, $usuarioDB, $contrasenyaDB);
// Comprobamso si recibimos datos por POST
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Prepara UPDATE
$miUpdate = $miPDO->prepare('UPDATE libros SET titulo = :titulo, autor = :autor, disponible = :disponible WHERE codigo = :codigo');
// Ejecuta UPDATE con los datos
$miUpdate->execute(
[
'codigo' => $codigo,
'titulo' => $titulo,
'autor' => $autor,
'disponible' => $disponible
]
);
// Redireccionamos a Leer
header('Location: leer.php');
} else {
// Prepara SELECT
$miConsulta = $miPDO->prepare('SELECT * FROM libros WHERE codigo = :codigo;');
// Ejecuta consulta
$miConsulta->execute(
[
codigo => $codigo
]
);
}
// Obtiene un resultado
$libro = $miConsulta->fetch();
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Crear - CRUD PHP</title>
</head>
<body>
<form method="post">
<p>
<label for="titulo">Titulo</label>
<input id="titulo" type="text" name="titulo" value="<?= $libro['titulo'] ?>">
</p>
<p>
<label for="autor">Autor</label>
<input id="autor" type="text" name="autor" value="<?= $libro['autor'] ?>">
</p>
<p>
<div>¿Disponible?</div>
<input id="si-disponible" type="radio" name="disponible" value="1"<?= $libro['disponible'] ? ' checked' : '' ?>> <label for="si-disponible">Si</label>
<input id="no-disponible" type="radio" name="disponible" value="0"<?= !$libro['disponible'] ? ' checked' : '' ?>> <label for="no-disponible">No</label>
</p>
<p>
<input type="hidden" name="codigo" value="<?= $codigo ?>">
<input type="submit" value="Modificar">
</p>
</form>
</body>
</html>
Borrar
Volvemos a tener una ruta con el código a eliminar.
borrar.php?codigo=3
Nuestro PHP lo capturaría, eliminaría el registro con DELETE y volvería a la página donde se muestra los datos.
Creamos un archivo llamado borrar.php e incluimos el siguiente código.
// Variables
$hostDB = '127.0.0.1';
$nombreDB = 'ejemplo';
$usuarioDB = 'root';
$contrasenyaDB = '';
// Conecta con base de datos
$hostPDO = "mysql:host=$hostDB;dbname=$nombreDB;";
$miPDO = new PDO($hostPDO, $usuarioDB, $contrasenyaDB);
// Obtiene codigo del libro a borrar
$codigo = isset($_REQUEST['codigo']) ? $_REQUEST['codigo'] : null;
// Prepara DELETE
$miConsulta = $miPDO->prepare('DELETE FROM libros WHERE codigo = :codigo');
// Ejecuta la sentencia SQL
$miConsulta->execute([
codigo => $codigo
]);
// Redireccionamos al PHP con todos los datos
header('Location: leer.php');
Consejo desde la experiencia: Nunca borres, sino desactiva. Añade una columna de tipo boolean que te permita activar o desactivar el datos. Entre otros puntos, evitarás problemas con algunas relaciones.
Actividad 1
La RAE te encarga montar un concurso de microrelatos de 100 palabras.
- Muestra un formulario donde se pueda enviar: título, relato, nombre y email.
- Guarda la información en la base de datos unicamente si los datos son correctos.
- Envía un email de confirmación.
- Lista en la parte inferior en relato con todos los anteriores.
- Enseña un contador con todos los relatos guardados.
- Añade un boton para dar un
Me gusta.
Actividad 2
Es hora de apuntar en algún sitio todas las series que has visto, son demasiadas y tu memoria muy corta.
- Realiza una tabla en MySQL con el nombre series.
- Crea un campo (input) para escribir el título y un botón con el texto "Añadir".
- Al pulsar sobre el botón se guardará en la tabla MySQL.
- Muestra todos los titulos de la base de datos en una tabla HTML.
- Incluye, en cada fila de la tabla, un botón con el texto "Borrar".
- Cuando sea pulsado, deberá desaparecer el título de la base de datos.
- Incluye, en cada fila de la tabla, un botón con el texto "Modificar".
- Al ser presionado te conducirá a una nueva página donde podrás modificar el texto del título. Al guardar el cambio te redireccionará de nuevo a la anterior página.
Pro:
- Añade a la tabla de MySQL el campo nota. Modifica tu actividad para que pueda incluir, además del título, la valoración entre el 0 y 10.
- Ordena los resultados por nota.
Pro 2:
- Realizar un buscador.
Actividad 3
- Realiza un CRUD para guardar la siguiente información: Nombre, apellidos, teléfono y Email.
Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional.
¿Me invitas a un café? ☕
Puedes hacerlo usando el terminal.
ssh customer@andros.dev -p 5555
Comentarios
Nuevo comentario
Nueva replica {{ formatEllipsisAuthor(replyComment.author) }}
Escribe el primer comentario
{{ comments.length }} comentarios