UD 4 Login MVC
RA 6 Desarrolla aplicaciones web de acceso a almacenes de datos, aplicando medidas para mantener la seguridad y la integridad de la información.
- a) Se han analizado las tecnologías que permiten el acceso mediante programación a la información disponible en almacenes de datos.
- b) Se han creado aplicaciones que establezcan conexiones con bases de datos.
- c) Se ha recuperado información almacenada en bases de datos.
- d) Se ha publicado en aplicaciones web la información recuperada.
- e) Se han utilizado conjuntos de datos para almacenar la información.
- f) Se han creado aplicaciones web que permitan la actualización y la eliminación de información disponible en una base de datos.
- g) Se han probado y documentado las aplicaciones web.
Ejemplo de un sistema básico de login donde vamos a aprender acerca de las consultas preparadas utilizando PDO, organizado con la estructura de carpetas Modelo-Vista-Controlador (MVC).
Estructura de carpetas
Usaremos la siguiente estructura de carpetas
project/
│
├── index.php # Archivo principal
├── .htaccess # Redirección a index.php (opcional)
├── app/
│ ├── controllers/
│ │ └── PersonaController.php
│ ├── models/
│ │ └── Persona.php
│ ├── views/
│ └── login.php
├── config/
│ └── database.php # Configuración de la base de datos
Estructura MCV
Puedes ayudarte con el siguienteenlace a la estructura MVC
1. Configuración de la base de datos (config/database.php)
<?php
class Database {
private $host = 'localhost';
private $dbName = 'dwes';
private $username = 'root';
private $password = '';
private $conn;
public function connect() {
try {
$this->conn = new PDO("mysql:host=$this->host;dbname=$this->dbName;charset=utf8", $this->username, $this->password);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $this->conn;
} catch (PDOException $e) {
die("Error de conexión: " . $e->getMessage());
}
}
}
?>
2. Modelo Persona (app/models/Persona.php)
<?php
require_once __DIR__ . '/../../config/database.php';
class Persona {
private $conn;
public function __construct() {
$db = new Database();
$this->conn = $db->connect();
}
public function login($nombre, $telefono) {
try {
$query = "SELECT * FROM persona WHERE nombre = :nombre AND telefono = :telefono";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(':nombre', $nombre);
$stmt->bindParam(':telefono', $telefono);
$stmt->execute();
return $stmt->fetch(PDO::FETCH_ASSOC); // Devuelve un registro si lo encuentra
} catch (PDOException $e) {
die("Error al realizar la consulta: " . $e->getMessage());
}
}
}
?>
3. Controlador PersonaController (app/controllers/PersonaController.php)
<?php
require_once __DIR__ . '/../models/Persona.php';
class PersonaController {
public function handleLogin() {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$nombre = $_POST['nombre'] ?? '';
$telefono = $_POST['telefono'] ?? '';
$personaModel = new Persona();
$persona = $personaModel->login($nombre, $telefono);
if ($persona) {
// Redirige al usuario si las credenciales son correctas
header('Location: app/views/welcome.php');
exit();
} else {
// En caso de error, muestra un mensaje
$error = "Credenciales incorrectas.";
require_once __DIR__ . '/../views/login.php';
}
} else {
require_once __DIR__ . '/../views/login.php';
}
}
}
?>
4. Vista Login (app/views/login.php)
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<?php if (isset($error)): ?>
<p style="color: red;"><?= $error ?></p>
<?php endif; ?>
<form method="POST" action="index.php">
<label for="nombre">Nombre:</label>
<input type="text" id="nombre" name="nombre" required>
<br>
<label for="telefono">Teléfono:</label>
<input type="text" id="telefono" name="telefono" required>
<br>
<button type="submit">Iniciar Sesión</button>
</form>
</body>
</html>
5. Archivo principal (index.php)
<?php
require_once __DIR__ . '/app/controllers/PersonaController.php';
$controller = new PersonaController();
$controller->handleLogin();
?>
6. Archivo welcome (
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Información sobre el ciclo formativo de informática">
<title>Ciclo Formativo de Informática</title>
<link rel="stylesheet" href="../../assets/css/styles.css">
</head>
<body>
<header>
<h1>Ciclo Formativo de Informática</h1>
</header>
<section class="introduction">
<h2>Bienvenidos</h2>
<p>
El ciclo formativo de informática está diseñado para preparar a los estudiantes en el uso de las tecnologías de la información, desarrollo de software, y administración de sistemas.
</p>
<img src="../../assets/images/cicloinformatica.jpg" alt="Ciclo Formativo de Informática">
</section>
<section class="content">
<h2>¿Qué aprenderás?</h2>
<ul>
<li>Programación en lenguajes como Java, Python y PHP.</li>
<li>Administración de bases de datos con MySQL y PostgreSQL.</li>
<li>Gestión de redes y sistemas operativos.</li>
<li>Desarrollo de aplicaciones web y móviles.</li>
</ul>
</section>
<footer>
<p>© 2024 Ciclo Formativo de Informática - Todos los derechos reservados.</p>
</footer>
</body>
</html>
Archivo de redirección (opcional: .htaccess)
Para ocultar el archivo index.php en la URL, utiliza este archivo en el directorio raíz:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
Base de datos
Crea la base de datos dwes
con la tabla persona
y algunos registros de ejemplo:
CREATE DATABASE dwes;
USE dwes;
CREATE TABLE persona (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(50) NOT NULL,
apellidos VARCHAR(100) NOT NULL,
telefono VARCHAR(15) NOT NULL
);
INSERT INTO persona (nombre, apellidos, telefono) VALUES
('Juan', 'Pérez', '123456789'),
('María', 'López', '987654321');
Flujo de la aplicación
- Inicio: El usuario accede al archivo
index.php
. - Controlador: Redirige al formulario de login o procesa el formulario enviado.
- Modelo: Realiza la consulta en la base de datos usando consultas preparadas con PDO.
- Vista: Muestra el formulario o los mensajes de error.
Nos fijamos en ...
Marcadores
Los marcadores son las palabras que querremos sustituir en la consulta (consulta preparada) y que van precedidas de los dos puntos si van con un nombre, también se pueden usar con signos de interrogación ?
Ejemplo con signos de interrogación (diferente al visto en el 4Login)
Nota cómo los valores van introducidos en la expresión **execute(150, red) ** en lugar de en la bindParam
<?php
/* Ejecuta una sentencia preparada pasando un array de valores */
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?');
$sth->execute(array(150, 'red'));
$red = $sth->fetchAll();
$sth->execute(array(175, 'yellow'));
$yellow = $sth->fetchAll();
?>
Método bindParam
Como se ve en el código del ejemplo anterior, antes de ejecutar la consulta tenemos que mapear los marcadores con el valor que deseamos consultar, que normalmente estará almacenado en una variable, array, etc..
Actividad
ProyectoUD4-PDO
La idea de esta unidad es aplicar las nuevas características adquiridas en un proyecto haciendo uso de la clase PDO para para accedera una base de datos.