0% encontró este documento útil (0 votos)
307 vistas54 páginas

Cómo Crear Una Aplicación CRUD Con PHP y MySQL

Este documento describe cómo crear una aplicación CRUD (Create, Read, Update, Delete) con PHP y MySQL sin usar ningún framework. Explica cómo configurar la base de datos, crear la plantilla HTML, desarrollar las funcionalidades CRUD mediante formularios y consultas SQL, y tomar consideraciones básicas de seguridad.

Cargado por

Videos Virales
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
307 vistas54 páginas

Cómo Crear Una Aplicación CRUD Con PHP y MySQL

Este documento describe cómo crear una aplicación CRUD (Create, Read, Update, Delete) con PHP y MySQL sin usar ningún framework. Explica cómo configurar la base de datos, crear la plantilla HTML, desarrollar las funcionalidades CRUD mediante formularios y consultas SQL, y tomar consideraciones básicas de seguridad.

Cargado por

Videos Virales
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 54

Cómo crear una aplicación CRUD con PHP y MySQL

En este tutorial vamos a ver cómo crear una aplicación CRUD con PHP y MySQL. Crearemos
tanto el backend como el frontend de la aplicación. No usaremos ningún framework, sino las
extensiones y los métodos nativos de PHP. La aplicación soportará la lectura, la escritura, la
actualización y el borrado de registros en la base de datos. Para las vistas usaremos
únicamente HTML y CSS.

Este es un tutorial de introducción especialmente creado para aquellas personas que se estén
iniciando con el desarrollo de aplicaciones con PHP. Por ello, no crearemos un gestor de rutas
ni usaremos composer. Tampoco dividiremos la aplicación en modelos, vistas y controladores
tal y como dicta el patrón de diseño MVC, siendo algo que dejaremos para otro tutorial.
#Contenidos

1 Introducción

2 Configuración del Host

3 Creación de la plantilla HTML

4 Configuración de la base de datos

4.1 Crea la base de datos

4.2 Crea el script de instalación

4.3 Ejecuta el script de instalación

5 Creación de la aplicación CRUD

5.1 CRUD (Create): Creación de alumnos

5.1.1 Formulario HTML

5.1.2 Código PHP

5.1.3 Ataques XSS

5.2 CRUD (Read): Lista de alumnos

5.2.1 Código PHP

5.2.2 Tabla HTML

5.2.3 Búsqueda

5.2.4 Acciones

5.3 CRUD (Update): Actualización de alumnos

5.3.1 Código PHP (Lectura)

5.3.2 Formulario HTML

5.3.3 Código PHP (Actualización)

5.4 CRUD (Delete): Borrado de alumnos

5.4.1 Código PHP

5.4.2 Código HTML

6 Protección CSRF

7 Conclusión
1.Introducción

Vamos a crear una sencilla aplicación que permita gestionar los datos de los
alumnos de un colegio. Necesitamos agregar las funcionalidades que nos
permitan crear un alumno, mostrar una lista de alumnos, editar los datos de un
alumno y eliminar un alumno.

Intentaremos usar las funcionalidades más recientes posibles de PHP y


tomaremos ciertas consideraciones de seguridad, aunque este tutorial no deja
de ser de aprendizaje. De todos modos, antes de continuar, es recomendable
que tengas unos conocimientos básicos de HTML y de PHP:

 Si nunca has usado HTML, consulta primero la guía definitiva de


HTML para aprender los conceptos más importantes.

 Si nunca has usado PHP, consulta la guía definitiva de PHP, en donde


además de aprender tus primeros pasos, verás cómo instalar y configurar
PHP en tu sistema operativo.

 Para gestionar las bases de datos MySQL usaremos phpMyAdmin, que es


una herramienta que se instala con paquetes como Wamp, XAMPP o
MAMP, aunque también puedes usar herramientas como Sequel Pro. De
todos modos, también veremos cómo crear todas las consultas MySQL
manualmente.

Lo primero que veremos en este tutorial será cómo conectarnos a una base de
datos MySQL con PHP usando PDO (PHP Data Objects). Seguidamente
crearemos un script que cree tanto la base de datos como las tablas de la
misma. Luego crearemos un formulario HTML que envíe datos al servidor. En
el servidor, usaremos sentencias preparadas para insertar registros en la base
de datos. Finalmente obtendremos los datos de la base de datos y los
mostraremos en una tabla HTML.

Puedes encontrar el código de la aplicación CRUD en GitHub.


2 configuración del Host

Lo primero que tenemos que hacer es crear un host virtual en nuestro sistema,
que es en donde crearemos el proyecto. Usaremos el servidor Apache, que se
instala con Wamp, que es la herramienta que utilizo en este proyecto. Si no
sabes cómo crear un host virtual, consulta el tutorial en donde explico cómo
crear un host virtual con Apache. En caso de que uses algún paquete todo en
uno, consulta una de estas guías.

 Host virtual con Wamp: Cómo crear un host virtual con Wamp

 Host virtual con MAMP: Cómo crear un host virtual con MAMP

 Host virtual con XAMPP: Cómo crear un host virtual con XAMPP

Vamos a crear el host virtual tutorial-crud.localhost. En mi caso, he


asignado el directorio /hosts/tutorial-crud al host virtual, pero puedes
asignar el que prefieras.
3 Creación de la plantilla HTML

Primero tenemos que crear una plantilla HTML para la aplicación junto con un
pequeño menú. No es el objetivo de este tutorial el de aprender CSS, por lo que
nos limitaremos a usar Bootstrap para los estilos.

En el interior del directorio del host virtual, crea un archivo vacío


llamado index.php. En teoría deberíamos agregar el código HTML de la
aplicación en el archivo index.php, tal que así:

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<meta name="viewport" content="width=device-width, initial-
scale=1" />

<title>Aplicación CRUD PHP</title>

<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/boo
tstrap.min.css" />
</head>

<body>
<h1>Aplicación CRUD PHP</h1>
<!-- Aquí el código HTML de la aplicación -->
</body>
</html>
Sin embargo, vamos a dividir la plantilla HTML en una cabecera y un pie que
compartirán todas las páginas de nuestra aplicación, por lo que, por ahora, es
mejor que dejes el archivo index.php vacío.

Para ello, crea un directorio llamado /templates, en cuyo interior debes crear
un archivo llamado header.php y otro llamado footer.php.
En archivo header.php contendrá la cabecera de la aplicación, por lo que debes
agregar este código HTML:

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<meta name="viewport" content="width=device-width, initial-
scale=1" />

<title>Aplicación CRUD PHP</title>

<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/boo
tstrap.min.css" />
</head>
<body>
Lo único que hemos hecho es agregar la declaración DOCTYPE y la
sección head de la aplicación, en donde hemos agregado el título y también
hemos incluido Bootstrap desde su CDN.

Seguidamente, debemos agregar el código del archivo footer.php, que se


limitará a cerrar las etiquetas body y html con este código:

</body>
</html>
Luego edita el archivo index.php y modifícalo para que contenga únicamente
este código, en donde agregamos el header y el footer que hemos creado:

<?php include "templates/header.php"; ?>


<!-- Aquí el código HTML de la aplicación -->
<?php include "templates/footer.php"; ?>
A continuación, vamos configurar la base de datos de la aplicación.
4 configuración de la base de datos

Para crear la base datos puedes usar alguna aplicación como MySQL
Workbench, SequelPro, Adminer o phpMyAdmin. En este tutorial, primero
crearemos la base de datos mediante una consulta SQL.

4.1 Crea la base de datos

Crea un directorio en la aplicación llamado /data y, en su interior, crea un


archivo vacío llamado, migracion.sql. En su interior, agrega esta consulta:

CREATE DATABASE tutorial_crud;

use tutorial_crud;

CREATE TABLE alumnos (


id INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(30) NOT NULL,
apellido VARCHAR(30) NOT NULL,
email VARCHAR(50) NOT NULL,
edad INT(3),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Lo que hemos hecho en este script es crear la base de datos, a la que
llamamos tutorial_crud. Luego usamos la sentencia use para seleccionar la
base de datos que hemos creado y luego creamos la tabla alumnos junto a sus
campos. Primero definimos el nombre de los campos y seguidamente su tipo:

 Usamos int(11) para definir campos que contengan un número entero


con una longitud de hasta 11 números.

 Usamos varchar(n) para definir cadenas que contengan


hasta n caracteres.

 Usamos TIMESTAMP para definir un campo que contenga una fecha en


formato YYYY-MM-DD HH:MI:SS.
Los campos created_at y updated_at guardarán la fecha de creación y de
actualización de los alumnos respectivamente. Además, también hemos usado
la sentencia NOT NULL para evitar que los campos puedan estar vacíos. No será
posible insertar un registro en la tabla si un campo NOT NULL está vacío.

También asignamos la fecha actual como la fecha por defecto de los


campos created_at y updated_at mediante la sentencia DEFAULT y el
valor CURRENT_TIMESTAMP.

Si quieres puedes probar la consulta antes de usarla en el código. Para ello


sigue estos los pasos que ves a continuación.

 Accede a phpMyAdmin o a la herramienta que utilices:


 Luego accede a la sección que permite ejecutar consulta SQL y copia y
pega la consulta anterior:

 Luego ejecuta la consulta haciendo clic en continuar en el caso de


phpMyAdmin. Esta consulta debería crear la base de datos.

Si has creado la base de datos y no ha habido errores, significa que todo


funciona como debería. Seguidamente borra la base de datos, ya que lo que
pretendemos es crearla mediante un script PHP.
4.2Crea el script de instalación

Vamos a crear un script que nos permita conectarnos a MySQL para crear la
base de datos. Podemos usar la interfaz PDO (PHP Data Objects) o podemos
usar MySQLi. La diferencia consiste en que con PDO nos podemos conectar a
más bases de datos que no necesariamente han de ser MySQL, siendo más
versátil que MySQLi, que solamente funcionará con bases de datos MySQL.
Además, PDO es más extensible y abierto de cara al futuro, haciendo que las
aplicaciones sean más fáciles de mantener.

El constructor de la clase PDO necesita que le pasemos el host de conexión a la


base de datos, el nombre de usuario MySQL, la contraseña y finalmente las
opciones de conexión. Para evitar repetir estos datos en varios archivos, crea el
archivo de configuración config.php en el directorio raíz de la aplicación:

<?php

return [
'db' => [
'host' => 'localhost',
'user' => 'root',
'pass' => 'root',
'name' => 'tutorial_crud',
'options' => [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]
]
];
Lo que hemos hecho ha sido definir un array de configuración que será devuelto
por el archivo. En el array db hemos definido los parámetros y opciones que
usaremos para conectarnos a la base de datos.

Ahora crea un archivo llamado instalar.php en el directorio raíz del proyecto


y, en su interior, incluye el array de configuración y asigna una nueva instancia
de la clase PDO a una variable, a la que llamaremos $conexion. Para crear el
objeto PDO usaremos los datos del array de configuración:

$config = include 'config.php';


$conexion = new PDO('mysql:host=' . $config['db']['host'],
$config['db']['user'], $config['db']['pass'], $config['db']
['options']);
Como ves, el primer parámetro es una cadena de texto que incluye el tipo de la
base de datos, el host y opcionalmente el nombre de la base de datos como
parte de ella. A este cadena se le llama DSN.

Ahora que ya hemos creado la conexión, vamos a asignar nuestra consulta SQL
a una variable usando el método file_get_contents y, seguidamente,
usaremos el método exec para ejecutar la consulta:

$sql = file_get_contents('data/migracion.sql');
$conexion->exec($sql);
A continuación puedes ver el contenido final del archivo instalar.php, en el
que también hemos agregado un bloque try/catch para que se muestre algún
error en caso de haberlo:

<?php
$config = include 'config.php';

try {
$conexion = new PDO('mysql:host=' . $config['db']['host'],
$config['db']['user'], $config['db']['pass'], $config['db']
['options']);
$sql = file_get_contents("data/migracion.sql");

$conexion->exec($sql);
echo "La base de datos y la tabla de alumnos se han creado con
éxito.";
} catch(PDOException $error) {
echo $error->getMessage();
}
Tal y como ves, la sentencia catch del bloque try/catch recibirá una
excepción de tipo PDOException como parámetro.
4.3 Ejecuta el script de instalación

Para ejecutar el script de instalación, accede a la URL /instalar.php desde tu


navegador. En mi caso, accederé a la
URL tutorial-crud.localhost/instalar.php. Deberías ver el siguiente
mensaje:

Si se muestra un mensaje de error en el que se dice que la base de datos ya


existe, recuerda que deberías haberla eliminado desde la aplicación gestora de
bases de datos.

5 Creación de la aplicación CRUD

Tenemos que crear una página que nos permita crear un alumno, otra que nos
permita listarlos y otra que nos permita actualizarlos. Además, también
necesitaremos un script que sea capaz de eliminar usuarios. Veamos cada uno
de estos apartados de la aplicación CRUD por separado.

CRUD (Create): Creación de alumnos

Crea un archivo llamado crear. Php en el directorio raíz de la aplicación. En


este archivo agregaremos un formulario que nos permita crear un alumno. Pero
primero debemos agregar un enlace al mismo en el archivo index.php:

<?php include "templates/header.php"; ?>

<div class="container">
<div class="row">
<div class="col-md-12">
<a href="crear.php" class="btn btn-primary mt-4">Crear
alumno</a>
<hr>
</div>
</div>
</div>

<?php include "templates/footer.php"; ?>


Lo único que hemos hecho ha sido agregar un botón que nos permita acceder
al archivo create.php.

Formulario HTML

Primero incluiremos los archivos header.php y footer.php en el


archivo crear.php. También agregaremos un formulario HTML que nos
permita introducir los datos de un alumno:

<?php include "templates/header.php"; ?>

<div class="container">
<div class="row">
<div class="col-md-12">
<h2 class="mt-4">Crea un alumno</h2>
<hr>
<form method="post">
<div class="form-group">
<label for="nombre">Nombre</label>
<input type="text" name="nombre" id="nombre"
class="form-control">
</div>
<div class="form-group">
<label for="apellido">Apellido</label>
<input type="text" name="apellido" id="apellido"
class="form-control">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" name="email" id="email"
class="form-control">
</div>
<div class="form-group">
<label for="edad">Edad</label>
<input type="text" name="edad" id="edad" class="form-
control">
</div>
<div class="form-group">
<input type="submit" name="submit" class="btn btn-
primary" value="Enviar">
<a class="btn btn-primary" href="index.php">Regresar
al inicio</a>
</div>
</form>
</div>
</div>
</div>

<?php include "templates/footer.php"; ?>


Hemos agregado el atributo name a cada campo <input> del formulario. El
valor del atributo name será el nombre que tendrá cada campo cuando se envíe
el formulario.

Hemos agregado también una etiqueta <label> para cada campo, que se
relacionará con su correspondiente campo gracias al atributo for. El valor del
atributo for es el mismo que el del atributo id del campo con el que se
relaciona. El uso de etiquetas label permite que las páginas sean más
accesibles.

No hemos especificado ninguna acción en el formulario, por lo que éste se


enviará a la misma página en la que está definido. Por ahora, dado que todavía
no hemos agregado el código PHP, no ocurrirá nada.

Si accedes al proyecto desde tu navegador, este será el resultado del formulario:

Tras crear el formulario, pasaremos a la parte backend, que es el código que


ejecutará el servidor para insertar el usuario en la base de datos.

Código PHP

Cuando envías el formulario, los datos se enviarán al propio script crear.php.


Podrás encontrarlos indexados en el interior del array $_POST. Por ejemplo, el
nombre que introduzcas en el campo cuyo atributo name es nombre, estará en la
variable $_POST['nombre']. Del mismo modo, el nombre que introduzcas en el
campo cuyo atributo name es apellido, estará en la
variable $_POST['apellido'].

Para comprobar si el formulario se ha enviado, puedes usar la siguiente


sentencia:

if (isset($_POST['submit'])) {
// Acciones a realizar
}
Para insertar un usuario también debemos conectarnos a MySQL, pero ahora
deberemos especificar también el nombre de la base de datos en el parámetros
DSN.

A continuación, agrega este código al inicio del archivo crear.php:

<?php

if (isset($_POST['submit'])) {

$resultado = [
'error' => false,
'mensaje' => 'Usuario agregado con éxito'
];

$config = include 'config.php';

try {
$dsn = 'mysql:host=' . $config['db']['host'] . ';dbname=' .
$config['db']['name'];
$conexion = new PDO($dsn, $config['db']['user'],
$config['db']['pass'], $config['db']['options']);

// Código que insertará un alumno

} catch(PDOException $error) {
$resultado['error'] = true;
$resultado['mensaje'] = $error->getMessage();
}
}
El array $resultado almacenará algún posible error, de haberlo. Luego hemos
incluido el array de configuración del archivo config.php y nos hemos
conectado a la base de datos. Esta vez hemos definido el nombre de la base de
datos a la que nos conectamos.

Hemos usado un bloque try/catch, en cuyo interior insertamos el usuario. De


haber algún error, se ejecutará el bloque catch, en donde almacenamos el error
en el array resultado.

Tal y como ves, he escrito un comentario con la localización en la que debes


agregar el código encargado de crear un nuevo usuario en la base de datos.
Ahora debes crear un array con los datos del nuevo alumno, que obtendremos
del array $_POST:

$alumno = [
"nombre" => $_POST['nombre'],
"apellido" => $_POST['apellido'],
"email" => $_POST['email'],
"edad" => $_POST['edad'],
];
En teoría deberíamos sanitizar los datos de entrada. Sin embargo, dado que
usaremos sentencias preparadas de PHP, no es necesario. Usaremos una
sentencia INSERT MySQL:

INSERT INTO users (nombre, apellido, email, edad) values


(:nombre, :apellido, :email, :edad)
Este sería el código PHP que implementa la consulta. Hemos usado dos líneas
para que sea más legible:

$consultaSQL = "INSERT INTO alumnos (nombre, apellido, email,


edad)";
$consultaSQL .= "values (:" . implode(", :",
array_keys($alumno)) . ")";
A continuación vamos a usar el método prepare y a ejecutar la consulta:

$sentencia = $conexion->prepare($consultaSQL);
$sentencia->execute($alumno);
Vamos a agregar también un mensaje de confirmación justo después del lugar
en el que incluimos el archivo header.php, en donde mostraremos un error, de
haberlo, o un mensaje de éxito si el alumno se ha insertado correctamente:

<?php
if (isset($resultado)) {
?>
<div class="container mt-3">
<div class="row">
<div class="col-md-12">
<div class="alert alert-<?= $resultado['error'] ?
'danger' : 'success' ?>" role="alert">
<?= $resultado['mensaje'] ?>
</div>
</div>
</div>
</div>
<?php
}
?>
Este sería el código PHP completo que usamos para crear el usuario:

<?php
if (isset($_POST['submit'])) {
$resultado = [
'error' => false,
'mensaje' => 'El alumno ' . $_POST['nombre'] . ' ha sido
agregado con éxito'
];
$config = include 'config.php';

try {
$dsn = 'mysql:host=' . $config['db']['host'] . ';dbname=' .
$config['db']['name'];
$conexion = new PDO($dsn, $config['db']['user'],
$config['db']['pass'], $config['db']['options']);
$alumno = array(
"nombre" => $_POST['nombre'],
"apellido" => $_POST['apellido'],
"email" => $_POST['email'],
"edad" => $_POST['edad'],
);

$consultaSQL = "INSERT INTO alumnos (nombre, apellido,


email, edad)";
$consultaSQL .= "values (:" . implode(", :",
array_keys($alumno)) . ")";

$sentencia = $conexion->prepare($consultaSQL);
$sentencia->execute($alumno);

} catch(PDOException $error) {
$resultado['error'] = true;
$resultado['mensaje'] = $error->getMessage();
}
}
?>

<?php include "templates/header.php"; ?>

<?php
if (isset($resultado)) {
?>
<div class="container mt-3">
<div class="row">
<div class="col-md-12">
<div class="alert alert-<?= $resultado['error'] ?
'danger' : 'success' ?>" role="alert">
<?= $resultado['mensaje'] ?>
</div>
</div>
</div>
</div>
<?php
}
?>
Ahora ya podrías enviar el formulario. Deberías ver el siguiente mensaje una vez
lo envíes:

Si embargo, todavía podemos mejorar el formulario.

Ataques XSS

Cuando creamos un alumno con éxito, mostramos su nombre en el mensaje de


confirmación. Imprimimos por pantalla directamente el resultado de la
variable $_POST, lo cual podría tener ciertos efectos indeseables si algún
atacante inyecta código malicioso en esta variable.

Para evitar ataques XSS vamos a codificar los caracteres especiales en sus
respectivas versiones HTML. Para simplificar el proceso, crearemos una función
reutilizable.
Crea el archivo funciones.php en el directorio raíz del proyecto y agrega esta
función:

function escapar($html) {
return htmlspecialchars($html, ENT_QUOTES | ENT_SUBSTITUTE,
"UTF-8");
}
Lo que hace la función es codificar cualquier caracter en su versión HTML.
Luego, incluye el archivo funciones.php en la parte superior del
archivo create.php:

include 'funciones.php';
Seguidamente, usa la función escapar con el elemento $_POST['nombre'] en
el array $resultado:

$resultado = [
'error' => false,
'mensaje' => 'El alumno ' . escapar($_POST['nombre']) . ' ha
sido agregado con éxito'
];
Este sería el código final completo del archivo crear.php:

<?php

include 'funciones.php';

if (isset($_POST['submit'])) {
$resultado = [
'error' => false,
'mensaje' => 'El alumno ' . escapar($_POST['nombre']) . ' ha
sido agregado con éxito'
];

$config = include 'config.php';

try {
$dsn = 'mysql:host=' . $config['db']['host'] . ';dbname=' .
$config['db']['name'];
$conexion = new PDO($dsn, $config['db']['user'],
$config['db']['pass'], $config['db']['options']);

$alumno = array(
"nombre" => $_POST['nombre'],
"apellido" => $_POST['apellido'],
"email" => $_POST['email'],
"edad" => $_POST['edad'],
);

$consultaSQL = "INSERT INTO alumnos (nombre, apellido,


email, edad) values (:" . implode(", :", array_keys($alumno)) .
")";

$sentencia = $conexion->prepare($consultaSQL);
$sentencia->execute($alumno);

} catch(PDOException $error) {
$resultado['error'] = true;
$resultado['mensaje'] = $error->getMessage();
}
}
?>

<?php include 'templates/header.php'; ?>

<?php
if (isset($resultado)) {
?>
<div class="container mt-3">
<div class="row">
<div class="col-md-12">
<div class="alert alert-<?= $resultado['error'] ?
'danger' : 'success' ?>" role="alert">
<?= $resultado['mensaje'] ?>
</div>
</div>
</div>
</div>
<?php
}
?>

<div class="container">
<div class="row">
<div class="col-md-12">
<h2 class="mt-4">Crea un alumno</h2>
<hr>
<form method="post">
<div class="form-group">
<label for="nombre">Nombre</label>
<input type="text" name="nombre" id="nombre"
class="form-control">
</div>
<div class="form-group">
<label for="apellido">Apellido</label>
<input type="text" name="apellido" id="apellido"
class="form-control">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" name="email" id="email"
class="form-control">
</div>
<div class="form-group">
<label for="edad">Edad</label>
<input type="text" name="edad" id="edad" class="form-
control">
</div>
<div class="form-group">
<input type="submit" name="submit" class="btn btn-
primary" value="Enviar">
<a class="btn btn-primary" href="index.php">Regresar
al inicio</a>
</div>
</form>
</div>
</div>
</div>

<?php include 'templates/footer.php'; ?>

CRUD (Read): Lista de alumnos

Vamos a crear la página usada para mostrar los datos de los alumnos. Para ello
usaremos el archivo index.php, en donde incluiremos tanto el
archivo header.php como el archivo footer.php.

Código PHP

Después del botón que nos permite acceder a la página crear.php vamos a
agregar una tabla con la lista de alumnos existentes. Sin embargo, primero
necesitamos obtener la lista de alumnos desde la base de datos. Por ello, debes
agregar este código al principio del archivo index.php:

<?php
include 'funciones.php';

$error = false;
$config = include 'config.php';

try {
$dsn = 'mysql:host=' . $config['db']['host'] . ';dbname=' .
$config['db']['name'];
$conexion = new PDO($dsn, $config['db']['user'], $config['db']
['pass'], $config['db']['options']);

// Código que obtendrá la lista de alumnos


} catch(PDOException $error) {
$error = $error->getMessage();
}
?>
Lo que hemos hecho ha sido incluir el archivo funciones.php y también el
array de configuración. Luego nos conectamos a la base de datos en un
bloque try/catch. De haber algún error, lo almacenamos en la
variable $error.

La consulta MySQL que usaremos para obtener la lista de alumnos será la


siguiente, que sencillamente obtendrá la lista completa de alumnos

$sql = "SELECT * FROM alumnos;


Este será el código PHP que implementa y ejecuta la consulta:

$consultaSQL = "SELECT * FROM alumnos";

$sentencia = $conexion->prepare($consultaSQL);
$sentencia->execute();
Luego almacenamos el resultado en la variable $alumnos:

$alumnos = $sentencia->fetchAll();
En caso de que se produzca algún error debes mostrarlo. Para ello, agrega el
siguiente código justo después del lugar en donde incluimos el
archivo header.php:

<?php
if ($error) {
?>
<div class="container mt-2">
<div class="row">
<div class="col-md-12">
<div class="alert alert-danger" role="alert">
<?= $error ?>
</div>
</div>
</div>
</div>
<?php
}
?>
Este sería el código PHP del archivo index.php con lo que hemos hecho hasta
ahora.

<?php
include 'funciones.php';

$error = false;
$config = include 'config.php';

try {
$dsn = 'mysql:host=' . $config['db']['host'] . ';dbname=' .
$config['db']['name'];
$conexion = new PDO($dsn, $config['db']['user'], $config['db']
['pass'], $config['db']['options']);

$consultaSQL = "SELECT * FROM alumnos";

$sentencia = $conexion->prepare($consultaSQL);
$sentencia->execute();

$alumnos = $sentencia->fetchAll();

} catch(PDOException $error) {
$error= $error->getMessage();
}
?>

<?php include "templates/header.php"; ?>

<?php
if ($error) {
?>
<div class="container mt-2">
<div class="row">
<div class="col-md-12">
<div class="alert alert-danger" role="alert">
<?= $error ?>
</div>
</div>
</div>
</div>
<?php
}
?>

<div class="container">
<div class="row">
<div class="col-md-12">
<a href="crear.php" class="btn btn-primary mt-4">Crear
alumno</a>
<hr>
</div>
</div>
</div>

<?php include "templates/footer.php"; ?>


Ahora ya solamente nos falta mostrar los resultados en una tabla.

Tabla HTML

Vamos a mostrar la lista de alumnos en una tabla HTML. Sin embargo, primero
agregaremos un mensaje que se ejecute en caso de que se haya producido
algún error al obtener la lista de alumnos.

A continuación puedes ver el código de la tabla. Agrega este código justo


después del bloque en donde mostramos el botón que redirige a la página que
permite crear alumnos, y antes del lugar en donde incluimos el
archivo footer.php:

<div class="container">
<div class="row">
<div class="col-md-12">
<h2 class="mt-3">Lista de alumnos</h2>
<table class="table">
<thead>
<tr>
<th>#</th>
<th>Nombre</th>
<th>Apellido</th>
<th>Email</th>
<th>Edad</th>
</tr>
</thead>
<tbody>
<?php
if ($alumnos && $sentencia->rowCount() > 0) {
foreach ($alumnos as $fila) {
?>
<tr>
<td><?php echo escapar($fila["id"]); ?></td>
<td><?php echo escapar($fila["nombre"]); ?></td>
<td><?php echo escapar($fila["apellido"]); ?
></td>
<td><?php echo escapar($fila["email"]); ?></td>
<td><?php echo escapar($fila["edad"]); ?></td>
</tr>
<?php
}
}
?>
<tbody>
</table>
</div>
</div>
</div>
Lo que hacemos es comprobar que existen alumnos mediante el
método rowCount y recorrer la lista de alumnos, agregando una fila a la tabla
por cada uno de los alumnos.

Este sería el código del archivo index.php con lo que hemos hecho hasta
ahora:

<?php
include 'funciones.php';

$error = false;
$config = include 'config.php';

try {
$dsn = 'mysql:host=' . $config['db']['host'] . ';dbname=' .
$config['db']['name'];
$conexion = new PDO($dsn, $config['db']['user'], $config['db']
['pass'], $config['db']['options']);

$consultaSQL = "SELECT * FROM alumnos";

$sentencia = $conexion->prepare($consultaSQL);
$sentencia->execute();

$alumnos = $sentencia->fetchAll();

} catch(PDOException $error) {
$error= $error->getMessage();
}
?>

<?php include "templates/header.php"; ?>

<?php
if ($error) {
?>
<div class="container mt-2">
<div class="row">
<div class="col-md-12">
<div class="alert alert-danger" role="alert">
<?= $error ?>
</div>
</div>
</div>
</div>
<?php
}
?>

<div class="container">
<div class="row">
<div class="col-md-12">
<a href="crear.php" class="btn btn-primary mt-4">Crear
alumno</a>
<hr>
</div>
</div>
</div>

<div class="container">
<div class="row">
<div class="col-md-12">
<h2 class="mt-3">Lista de alumnos</h2>
<table class="table">
<thead>
<tr>
<th>#</th>
<th>Nombre</th>
<th>Apellido</th>
<th>Email</th>
<th>Edad</th>
</tr>
</thead>
<tbody>
<?php
if ($alumnos && $sentencia->rowCount() > 0) {
foreach ($alumnos as $fila) {
?>
<tr>
<td><?php echo escapar($fila["id"]); ?></td>
<td><?php echo escapar($fila["nombre"]); ?></td>
<td><?php echo escapar($fila["apellido"]); ?
></td>
<td><?php echo escapar($fila["email"]); ?></td>
<td><?php echo escapar($fila["edad"]); ?></td>
</tr>
<?php
}
}
?>
<tbody>
</table>
</div>
</div>
</div>

<?php include "templates/footer.php"; ?>


Si agregas algunos alumnos y luego accedes a la página principal de la
aplicación usando tu navegador, deberías ver este resultado:
Ya hemos terminado, pero vamos a agregar una funcionalidad a mayores. Se
trata de un formulario que nos permitirá filtrar la lista de alumnos.

Búsqueda

Estaría bien agregar un campo de búsqueda que nos permita buscar usuarios
por apellido. Para ello crearemos el siguiente formulario debajo de la línea de
separación que hemos agregado, debajo del enlace hacia la página crear.php:

<div class="container">
<div class="row">
<div class="col-md-12">
<a href="crear.php" class="btn btn-primary mt-4">Crear
alumno</a>
<hr>
<form method="post" class="form-inline">
<div class="form-group mr-3">
<input type="text" id="apellido" name="apellido"
placeholder="Buscar por apellido" class="form-control">
</div>
<button type="submit" name="submit" class="btn btn-
primary">Ver resultados</button>
</form>
</div>
</div>
</div>
Hemos usado el atributo placeholder en el campo nombre del formulario para
mostrar un texto por defecto, que desaparecerá cuando introduzcamos algo en
él.

Seguidamente, accede al proyecto desde tu navegador para ver el resultado:

El formulario enviará el apellido del alumno que introduzcamos a la propia


página, por lo que debemos agregar una consulta SQL alternativa que se
ejecute cuando el formulario se haya enviado:

if (isset($_POST['apellido'])) {
$consultaSQL = "SELECT * FROM alumnos WHERE apellido LIKE '%"
. $_POST['apellido'] . "%'";
} else {
$consultaSQL = "SELECT * FROM alumnos";
}
El operador MySQL LIKE buscará los alumnos cuyo apellido contenga la
subadena que introduzcamos en el campo apellido. El símbolo % sirve para
especificar que puede haber texto a la izquierda o a la derecha de la cadena.

Vamos a modificar también el título del formulario, de modo que indiquemos


cuando estemos realizando una búsqueda por apellido. Para ello, asignaremos
el título del formulario mediante PHP:
$titulo = isset($_POST['apellido']) ? 'Lista de alumnos (' .
$_POST['apellido'] . ')' : 'Lista de alumnos';
Hemos usado el operador ternario de PHP para comprobar si el apellido está
presente en el array $_POST, en cuyo caso agregamos el apellido entre
paréntesis al título:

Por ahora hemos visto cómo conectarnos a la base de datos mediante PDO,
cómo crear un script de instalación y cómo listar y agregar registros. En una
aplicación real también tendríamos que agregar gestión de usuarios, una página
de login o validaciones JavaScript entre otras cosas, aunque es algo que sale
del alcance de este tutorial.

Acciones

Antes de continuar, vamos a agregar una columna más a nuestra tabla que
contenga dos enlaces para cada fila. Los enlaces enlazarán al
archivo editar.php y al archivo borrar.php respectivamente. Para ello
agregamos una cabecera adicional a la tabla:

<thead>
<tr>
<!-- ... -->
<th>Acciones</th>
</tr>
</thead>
También agregaremos una columna más con las acciones al cuerpo de la tabla:
<td>

<a href="<?= 'borrar.php?id=' . escapar($fila["id"]) ?>">


Borrar</a>
<a href="<?= 'editar.php?id=' . escapar($fila["id"]) ?

>">Editar</a>
</td>
Tal y como ves, enviamos el id del usuario que queremos borrar o que
queremos actualizar a las páginas borrar.php y editar.php respectivamente.
Estas páginas todavía nos las hemos creado.

Este será el resultado:

Este es el código completo final del archivo index.php:

<?php
include 'funciones.php';

$error = false;
$config = include 'config.php';

try {
$dsn = 'mysql:host=' . $config['db']['host'] . ';dbname=' .
$config['db']['name'];
$conexion = new PDO($dsn, $config['db']['user'], $config['db']
['pass'], $config['db']['options']);

if (isset($_POST['apellido'])) {
$consultaSQL = "SELECT * FROM alumnos WHERE apellido LIKE
'%" . $_POST['apellido'] . "%'";
} else {
$consultaSQL = "SELECT * FROM alumnos";
}

$sentencia = $conexion->prepare($consultaSQL);
$sentencia->execute();

$resultados = $sentencia->fetchAll();

} catch(PDOException $error) {
$error= $error->getMessage();
}

$titulo = isset($_POST['apellido']) ? 'Lista de alumnos (' .


$_POST['apellido'] . ')' : 'Lista de alumnos';
?>

<?php include "templates/header.php"; ?>

<?php
if ($error) {
?>
<div class="container mt-2">
<div class="row">
<div class="col-md-12">
<div class="alert alert-danger" role="alert">
<?= $error ?>
</div>
</div>
</div>
</div>
<?php
}
?>

<div class="container">
<div class="row">
<div class="col-md-12">
<a href="crear.php" class="btn btn-primary mt-4">Crear
alumno</a>
<hr>
<form method="post" class="form-inline">
<div class="form-group mr-3">
<input type="text" id="apellido" name="apellido"
placeholder="Buscar por apellido" class="form-control">
</div>
<button type="submit" name="submit" class="btn btn-
primary">Ver resultados</button>
</form>
</div>
</div>
</div>

<div class="container">
<div class="row">
<div class="col-md-12">
<h2 class="mt-3"><?= $titulo ?></h2>
<table class="table">
<thead>
<tr>
<th>#</th>
<th>Nombre</th>
<th>Apellido</th>
<th>Email</th>
<th>Edad</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<?php
if ($alumnos && $sentencia->rowCount() > 0) {
foreach ($alumnos as $fila) {
?>
<tr>
<td><?php echo escapar($fila["id"]); ?></td>
<td><?php echo escapar($fila["nombre"]); ?></td>
<td><?php echo escapar($fila["apellido"]); ?
></td>
<td><?php echo escapar($fila["email"]); ?></td>
<td><?php echo escapar($fila["edad"]); ?></td>
<td>
<a href="<?= 'borrar.php?id=' .

escapar($fila["id"]) ?>">Borrar</a>
<a href="<?= 'editar.php?id=' .

escapar($fila["id"]) ?>" . >✏️Editar</a>


</td>
</tr>
<?php
}
}
?>
<tbody>
</table>
</div>
</div>
</div>

<?php include "templates/footer.php"; ?>


CRUD (Update): Actualización de alumnos

Vamos a agregar una página que nos permita editar un usuario. Para ello crea el
archivo editar.php en la carpeta raíz del proyecto con este contenido:

<?php require "templates/header.php"; ?>


<!-- código de la página -->
<?php require "templates/footer.php"; ?>
Necesitamos obtener los datos del usuario que estamos editando desde la base
de datos y mostrar un formulario de edición.

Código PHP (Lectura)

Primero incluimos el archivo funciones.php y el array de configuración.


Seguidamente comprobamos que el parámetro $_GET['id'] esté presente,
mostrando un error en caso contrario. Luego nos conectamos a la base de datos
para buscar el alumno que estamos editando.

Este es el código PHP que usamos para obtener el alumno que estamos
editando, que va al principio del archivo editar.php:

<?php
include 'funciones.php';

$config = include 'config.php';

$resultado = [
'error' => false,
'mensaje' => ''
];

if (!isset($_GET['id'])) {
$resultado['error'] = true;
$resultado['mensaje'] = 'El alumno no existe';
}

try {
$dsn = 'mysql:host=' . $config['db']['host'] . ';dbname=' .
$config['db']['name'];
$conexion = new PDO($dsn, $config['db']['user'], $config['db']
['pass'], $config['db']['options']);

$id = $_GET['id'];
$consultaSQL = "SELECT * FROM alumnos WHERE id =" . $id;

$sentencia = $conexion->prepare($consultaSQL);
$sentencia->execute();

$alumno = $sentencia->fetch(PDO::FETCH_ASSOC);

if (!$alumno) {
$resultado['error'] = true;
$resultado['mensaje'] = 'No se ha encontrado el alumno';
}

} catch(PDOException $error) {
$resultado['error'] = true;
$resultado['mensaje'] = $error->getMessage();
}
?>
Tal y como ves, en caso de no pasar ningún id a la página o de que ocurra
algún error, almacenamos el mensaje en el elemento $resultado['mensaje'].

Formulario HTML

A continuación debemos agregar un formulario con los datos actuales del


alumno que hemos obtenido desde la base de datos, que están en el
array $alumno. Este formulario es casi idéntico al que hemos agregado en el
archivo crear.php, con la salvedad de que en este caso los campos tendrán un
valor.

Sin embargo, primero debemos mostrar algún error en caso de que haya
ocurrido alguno. Para ello usa el siguiente código después de la línea en la que
incluimos el archivo header.php:
<?php
if ($resultado['error']) {
?>
<div class="container mt-2">
<div class="row">
<div class="col-md-12">
<div class="alert alert-danger" role="alert">
<?= $resultado['mensaje'] ?>
</div>
</div>
</div>
</div>
<?php
}
?>
En caso de que se haya enviado el formulario, tendremos que mostrar también
un mensaje de confirmación siempre y cuando no haya habido errores:

<?php
if (isset($_POST['submit']) && !$resultado['error']) {
?>
<div class="container mt-2">
<div class="row">
<div class="col-md-12">
<div class="alert alert-success" role="alert">
El alumno ha sido actualizado correctamente
</div>
</div>
</div>
</div>
<?php
}
?>
Seguidamente, tras los mensajes anteriores, agrega el código del formulario:

<?php
if (isset($alumno) && $alumno) {
?>
<div class="container">
<div class="row">
<div class="col-md-12">
<h2 class="mt-4">Editando el alumno <?=
escapar($alumno['nombre']) . ' ' . escapar($alumno['apellido'])
?></h2>
<hr>
<form method="post">
<div class="form-group">
<label for="nombre">Nombre</label>
<input type="text" name="nombre" id="nombre"
value="<?= escapar($alumno['nombre']) ?>" class="form-control">
</div>
<div class="form-group">
<label for="apellido">Apellido</label>
<input type="text" name="apellido" id="apellido"
value="<?= escapar($alumno['apellido']) ?>" class="form-
control">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" name="email" id="email"
value="<?= escapar($alumno['email']) ?>" class="form-control">
</div>
<div class="form-group">
<label for="edad">Edad</label>
<input type="text" name="edad" id="edad" value="<?=
escapar($alumno['edad']) ?>" class="form-control">
</div>
<div class="form-group">
<input type="submit" name="submit" class="btn btn-
primary" value="Actualizar">
<a class="btn btn-primary" href="index.php">Regresar
al inicio</a>
</div>
</form>
</div>
</div>
</div>
<?php
}
?>
Tal y como ves, solamente mostramos el formulario en caso de que se haya
obtenido un alumno. Hemos usado el atributo value de los
campos input HTML para definir el valor que tendrá cada campo.

Código PHP (Actualización)

Ahora que ya tenemos el formulario debemos definir las acciones a ejecutar


cuando se envíe. Para ello, debemos detectar si el
parámetro $_POST['submit'] está presente. Si es así, nos conectamos a la
base de datos y actualizamos el alumno con los nuevos datos. Para completar
esta tarea, agrega el siguiente código justo antes del bloque try/catch en el
que obtenemos los datos del alumno:

if (isset($_POST['submit'])) {
try {
$dsn = 'mysql:host=' . $config['db']['host'] . ';dbname=' .
$config['db']['name'];
$conexion = new PDO($dsn, $config['db']['user'],
$config['db']['pass'], $config['db']['options']);

// actualización del alumno

} catch(PDOException $error) {
$resultado['error'] = true;
$resultado['mensaje'] = $error->getMessage();
}
}
Ahora usaremos una sentencia SQL UPDATE para actualizar los valores del
alumno cuyo id se corresponde con el que estamos editando:

UPDATE alumnos
SET nombre = :nombre,
apellido = :apellido,
email = :email,
edad = :edad
updated_at = NOW()
WHERE id = :id
Tal y como ves, también actualizamos el campo updated_at con la fecha actual,
que obtenemos mediante la función NOW() de MySQL. Este sería el código PHP
que implementa la consulta anterior:

$alumno = [
"id" => $_GET['id'],
"nombre" => $_POST['nombre'],
"apellido" => $_POST['apellido'],
"email" => $_POST['email'],
"edad" => $_POST['edad']
];

$consultaSQL = "UPDATE alumnos SET


nombre = :nombre,
apellido = :apellido,
email = :email,
edad = :edad,
updated_at = NOW()
WHERE id = :id";

$consulta = $conexion->prepare($consultaSQL);
$consulta->execute($alumno);
Y con esto ya habremos actualizado los datos del alumno.

Este sería el resultado cuando editas un alumno correctamente:


Este es el código completo final del archivo editar.php:

<?php
include 'funciones.php';

$config = include 'config.php';

$resultado = [
'error' => false,
'mensaje' => ''
];

if (!isset($_GET['id'])) {
$resultado['error'] = true;
$resultado['mensaje'] = 'El alumno no existe';
}
if (isset($_POST['submit'])) {
try {
$dsn = 'mysql:host=' . $config['db']['host'] . ';dbname=' .
$config['db']['name'];
$conexion = new PDO($dsn, $config['db']['user'],
$config['db']['pass'], $config['db']['options']);

$alumno = [
"id" => $_GET['id'],
"nombre" => $_POST['nombre'],
"apellido" => $_POST['apellido'],
"email" => $_POST['email'],
"edad" => $_POST['edad']
];

$consultaSQL = "UPDATE alumnos SET


nombre = :nombre,
apellido = :apellido,
email = :email,
edad = :edad,
updated_at = NOW()
WHERE id = :id";

$consulta = $conexion->prepare($consultaSQL);
$consulta->execute($alumno);

} catch(PDOException $error) {
$resultado['error'] = true;
$resultado['mensaje'] = $error->getMessage();
}
}

try {
$dsn = 'mysql:host=' . $config['db']['host'] . ';dbname=' .
$config['db']['name'];
$conexion = new PDO($dsn, $config['db']['user'], $config['db']
['pass'], $config['db']['options']);

$id = $_GET['id'];
$consultaSQL = "SELECT * FROM alumnos WHERE id =" . $id;

$sentencia = $conexion->prepare($consultaSQL);
$sentencia->execute();

$alumno = $sentencia->fetch(PDO::FETCH_ASSOC);

if (!$alumno) {
$resultado['error'] = true;
$resultado['mensaje'] = 'No se ha encontrado el alumno';
}

} catch(PDOException $error) {
$resultado['error'] = true;
$resultado['mensaje'] = $error->getMessage();
}
?>

<?php require "templates/header.php"; ?>

<?php
if ($resultado['error']) {
?>
<div class="container mt-2">
<div class="row">
<div class="col-md-12">
<div class="alert alert-danger" role="alert">
<?= $resultado['mensaje'] ?>
</div>
</div>
</div>
</div>
<?php
}
?>

<?php
if (isset($_POST['submit']) && !$resultado['error']) {
?>
<div class="container mt-2">
<div class="row">
<div class="col-md-12">
<div class="alert alert-success" role="alert">
El alumno ha sido actualizado correctamente
</div>
</div>
</div>
</div>
<?php
}
?>

<?php
if (isset($alumno) && $alumno) {
?>
<div class="container">
<div class="row">
<div class="col-md-12">
<h2 class="mt-4">Editando el alumno <?=
escapar($alumno['nombre']) . ' ' . escapar($alumno['apellido'])
?></h2>
<hr>
<form method="post">
<div class="form-group">
<label for="nombre">Nombre</label>
<input type="text" name="nombre" id="nombre"
value="<?= escapar($alumno['nombre']) ?>" class="form-control">
</div>
<div class="form-group">
<label for="apellido">Apellido</label>
<input type="text" name="apellido" id="apellido"
value="<?= escapar($alumno['apellido']) ?>" class="form-
control">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" name="email" id="email"
value="<?= escapar($alumno['email']) ?>" class="form-control">
</div>
<div class="form-group">
<label for="edad">Edad</label>
<input type="text" name="edad" id="edad" value="<?=
escapar($alumno['edad']) ?>" class="form-control">
</div>
<div class="form-group">
<input type="submit" name="submit" class="btn btn-
primary" value="Actualizar">
<a class="btn btn-primary" href="index.php">Regresar
al inicio</a>
</div>
</form>
</div>
</div>
</div>
<?php
}
?>

<?php require "templates/footer.php"; ?>


CRUD (Delete): Borrado de alumnos

Vamos a agregar una página que nos permita borrar un alumno de la base de
datos. Para ello crea el archivo borrar.php en la carpeta raíz del proyecto con
este contenido:

<?php require "templates/header.php"; ?>


<!-- código de la página -->
<?php require "templates/footer.php"; ?>
Lo que haremos será ejecutar una consulta que borre el alumno cuyo id se
corresponde con el parámetro $_GET['id']. Si el alumno es borrado con éxito
redirigiremos al usuario a la página index.php. De lo contrario mostraremos un
mensaje de e error.

Código PHP

Primero vamos a conectarnos a la base de datos y a borrar el alumno, para


luego usar la función header para redirigir al usuario al archivo index.php.
Agrega este código antes de la línea en la que incluimos el archivo header.php:

<?php
include 'funciones.php';

$config = include 'config.php';

$resultado = [
'error' => false,
'mensaje' => ''
];

try {
$dsn = 'mysql:host=' . $config['db']['host'] . ';dbname=' .
$config['db']['name'];
$conexion = new PDO($dsn, $config['db']['user'], $config['db']
['pass'], $config['db']['options']);

$id = $_GET['id'];
$consultaSQL = "DELETE FROM alumnos WHERE id =" . $id;
$sentencia = $conexion->prepare($consultaSQL);
$sentencia->execute();

header('Location: /index.php');

} catch(PDOException $error) {
$resultado['error'] = true;
$resultado['mensaje'] = $error->getMessage();
}
?>

Código HTML

El siguiente código HTML solamente se mostrará si ha ocurrido algún error.


Agrega este código después de la línea donde incluimos el archivo header.php:

<div class="container mt-2">


<div class="row">
<div class="col-md-12">
<div class="alert alert-danger" role="alert">
<?= $resultado['mensaje'] ?>
</div>
</div>
</div>
</div>
Y con esto ya hemos terminado. Este sería el código completo final del
archivo borrar.php:

<?php
include 'funciones.php';

$config = include 'config.php';

$resultado = [
'error' => false,
'mensaje' => ''
];

try {
$dsn = 'mysql:host=' . $config['db']['host'] . ';dbname=' .
$config['db']['name'];
$conexion = new PDO($dsn, $config['db']['user'], $config['db']
['pass'], $config['db']['options']);

$id = $_GET['id'];
$consultaSQL = "DELETE FROM alumnos WHERE id =" . $id;

$sentencia = $conexion->prepare($consultaSQL);
$sentencia->execute();

header('Location: /index.php');

} catch(PDOException $error) {
$resultado['error'] = true;
$resultado['mensaje'] = $error->getMessage();
}
?>

<?php require "templates/header.php"; ?>

<div class="container mt-2">


<div class="row">
<div class="col-md-12">
<div class="alert alert-danger" role="alert">
<?= $resultado['mensaje'] ?>
</div>
</div>
</div>
</div>
<?php require "templates/footer.php"; ?>

Protección CSRF

Vamos a agregar protección contra ataques CSRF, mediante los cuales un


atacante puede engañar al navegador y ejecutar código no deseado. Lo que
haremos será almacenar un token CSRF en una variable de sesión del servidor.
Validaremos el token del servidor contra un valor que agregaremos en un
campo oculto de los formulario de la aplicación.

Edita el archivo funciones.php y agrega esta función, en la que generamos un


token que almacenamos en la variable de sesión $_SESSION['csrf']:

function csrf() {

session_start();

if (empty($_SESSION['csrf'])) {
if (function_exists('random_bytes')) {
$_SESSION['csrf'] = bin2hex(random_bytes(32));
} else if (function_exists('mcrypt_create_iv')) {
$_SESSION['csrf'] = bin2hex(mcrypt_create_iv(32,
MCRYPT_DEV_URANDOM));
} else {
$_SESSION['csrf'] =
bin2hex(openssl_random_pseudo_bytes(32));
}
}
}
Puede que no estén disponibles ciertas funciones en tu sistema, por lo que
intentamos generar el token de sesión con varias de las funciones más
habituales.

Luego, agrega este código tras incluir el archivo funciones.php en todas las
páginas de la aplicación.

include 'funciones.php';
csrf();
if (isset($_POST['submit']) && !hash_equals($_SESSION['csrf'],
$_POST['csrf'])) {
die();
}
Lo que hemos hecho es comprobar que el token CSRF de sesión sea igual que
el que agregaremos en el formulario. Si no es igual, finalizamos la ejecución de
la aplicación.

Luego, agrega este campo oculto a los formularios de la aplicación:

<input name="csrf" type="hidden" value="<?php echo


escapar($_SESSION['csrf']); ?>">
Al usar el atributo hidden, el campo se mantendrá oculto.

Conclusión

Y con esto ya habrás creado tu primera aplicació CRUD. Es más que


recomendable saber programar correctamente con PHP antes de aventurarse en
el uso de frameworks aunque a priori pueda paracer que usarlos es más sencillo.
De este modo, tendrás una idea más clara de lo que ocurre.

Esta aplicación todavía necesitaría más elementos para ser segura y poder ser
usada en producción, pero es una introducción que te resultará muy útil.

También podría gustarte