23. Hoy vamos a continuar con el tema de Lectura de Datos con PDO, Parte 2.
tutorial número 23. Hoy vamos a continuar con el tema de Lectura de Datos con PDO, Parte 2.
Vamos a tomar todo el código de las imágenes y el texto que me has proporcionado para construir un sistema de login funcional, paso a paso. Explicaremos cada error y cada corrección en el camino, porque de los errores se aprende mucho.
Objetivo del Tutorial: Conectar el formulario de ingreso con la base de datos para verificar si el usuario y la contraseña existen y coinciden. Si coinciden, que nos lleve a una página de "usuarios". Si no, que nos muestre un mensaje de "fallo".
Paso 1: Preparar el Formulario de Ingreso (ingresar.php)
Lo primero es tener nuestro formulario HTML. Es importante que los name de los campos coincidan exactamente con lo que vamos a buscar en PHP.
<!-- ingresar.php --> <h1>INGRESAR</h1> <form method="post"> <input type="text" placeholder="Usuario" name="usuarioIngreso" required> <input type="password" placeholder="Contraseña" name="passwordIngreso" required> <input type="submit" value="Enviar"> </form> <?php // Aquí llamaremos al controlador más adelante $ingreso = new MvcController(); $ingreso -> ingresosUsuarioController(); ?> <?php // Este código mostrará un mensaje si el login falla if (isset($_GET["action"])) { if ($_GET["action"] == "fallo") { echo "Fallo al ingresar"; } } ?>
Explicación para el alumno:
Creamos un formulario simple que envía los datos por método
POST.Los nombres de los campos (
usuarioIngreso,passwordIngreso) son los que usaremos en el controlador para capturar los datos.Al final, veremos un código PHP que muestra un mensaje si en la URL aparece
?action=fallo.
Paso 2: El Modelo - La Consulta a la Base de Datos (modelo.php)
El modelo es el encargado de hablar con la base de datos. Aquí usaremos PDO para preparar una consulta SELECT que busque un usuario específico.
<?php // modelo.php require_once "conexion.php"; class Datos extends Conexion{ // MODELO PARA EL INGRESO DE USUARIOS public function ingresosUsuarioModel($datosModel, $tabla){ // 1. Preparar la sentencia SQL // Seleccionamos usuario y password de la tabla que coincidan con el :usuario $stmt = Conexion::conectar()->prepare("SELECT usuario, password FROM $tabla WHERE usuario = :usuario"); // 2. Enlazar los parámetros // Vinculamos el marcador :usuario con el valor real que viene del formulario $stmt->bindParam(":usuario", $datosModel["usuario"], PDO::PARAM_STR); // 3. Ejecutar la consulta $stmt->execute(); // 4. Devolver el resultado // fetch(): Obtiene una sola fila del resultado. La devuelve como un arreglo. return $stmt->fetch(); } } ?>
Explicación para el alumno:
prepare(): Preparamos la consulta SQL. UsamosSELECTpara leer datos, a diferencia delINSERTque usábamos para registrar.:usuario: Es un parámetro de sustitución (un marcador). Evita que los usuarios malintencionados puedan inyectar código SQL.bindParam(): Enlaza el marcador:usuariocon el valor real que el usuario escribió en el inputusuarioIngreso. Es como decir: "Donde dice:usuario, pon el valor que viene en$datosModel["usuario"]".execute(): Ejecuta la consulta ya armada.fetch(): Este método es muy importante. Trae UNA SOLA FILA de la base de datos como un arreglo. Si el usuario existe, nos devolverá sus datos. Si no existe, devolveráfalse.
Paso 3: El Controlador - La Lógica de Negocio (controlador.php)
El controlador recibe los datos del formulario, se los pasa al modelo y, con la respuesta, decide qué hacer.
3.1 Primera versión del controlador (para ver qué nos devuelve el modelo)
Primero, vamos a hacer una prueba simple para ver qué datos nos está devolviendo el modelo. Esto nos ayudará a entender el error que vimos en la explicación.
<?php // controlador.php require_once "modelo.php"; class MvcController{ // CONTROLADOR PARA EL INGRESO DE USUARIOS public function ingresosUsuarioController(){ // Preguntamos si los datos del formulario están llegando if(isset($_POST["usuarioIngreso"])){ // Organizamos los datos del formulario en un arreglo $datosController = array( "usuario" => $_POST["usuarioIngreso"], "password" => $_POST["passwordIngreso"] ); // Llamamos al modelo y le enviamos los datos $respuesta = Datos::ingresosUsuarioModel($datosController, "usuarios"); // Mostramos lo que el modelo nos devolvió var_dump($respuesta); } } } ?>
Prueba y Error Común:
Abre tu navegador, ve a
ingresar.phpy escribe un usuario existente (ej: "pepe") y su contraseña.Haz clic en "Enviar".
Resultado esperado: Un
var_dump()del arreglo que devuelve la base de datos.array(4) { ["usuario"]=> string(4) "pepe" [0]=> string(4) "pepe" ["password"]=> string(4) "1234" [1]=> string(4) "1234" }¡Perfecto! El
fetch()nos devuelve un arreglo con los datos, accesibles tanto por el nombre de la columna ($respuesta["usuario"]) como por su índice numérico ($respuesta[0]).
Prueba con un usuario que NO existe:
Escribe un usuario falso, ej: "juanito".
El
var_dump()mostrarábool(false). El modelo no encontró nada.
Paso 4: Versión Final del Controlador con la Validación
Ahora que sabemos que la respuesta del modelo puede ser un array (si el usuario existe) o false (si no existe), podemos crear la lógica final.
<?php // controlador.php require_once "modelo.php"; class MvcController{ // CONTROLADOR PARA EL INGRESO DE USUARIOS (VERSIÓN FINAL) public function ingresosUsuarioController(){ if(isset($_POST["usuarioIngreso"])){ $datosController = array( "usuario" => $_POST["usuarioIngreso"], "password" => $_POST["passwordIngreso"] ); $respuesta = Datos::ingresosUsuarioModel($datosController, "usuarios"); // --- LÓGICA DE VALIDACIÓN --- // Preguntamos: ¿La respuesta es un arreglo? (es decir, ¿encontró al usuario?) // Y luego, ¿el usuario de la BD es igual al del POST? // ¿Y la contraseña de la BD es igual a la del POST? if(is_array($respuesta) && $respuesta["usuario"] == $_POST["usuarioIngreso"] && $respuesta["password"] == $_POST["passwordIngreso"]){ // SI TODO COINCIDE: Redirigimos a la página de usuarios header("location:index.php?action=usuarios"); }else{ // SI ALGO FALLA: Redirigimos al login con un mensaje de error header("location:index.php?action=fallo"); } // ---------------------------- } } } ?>
Explicación de la validación:
is_array($respuesta): Primero nos aseguramos de que el modelo nos haya devuelto un usuario. Si esfalse, esta condición falla de inmediato.$respuesta["usuario"] == $_POST["usuarioIngreso"]: Comparamos el nombre de usuario que trajo la BD contra el que el usuario escribió en el formulario. Aunque la BD ya nos devolvió el usuario que coincidía con:usuario, esta doble verificación es una buena práctica de seguridad.$respuesta["password"] == $_POST["passwordIngreso"]: Comparamos la contraseña. NOTA IMPORTANTE: En un proyecto real, las contraseñas NUNCA se guardan en texto plano como "1234". Se guardan encriptadas con funciones comopassword_hash(). La comparación se haría conpassword_verify(). Pero para este ejemplo didáctico, las comparamos directamente.header("location:..."): Esta función de PHP redirige al usuario a otra página. Es crucial usarla antes de que haya cualquier salida de HTML en la página.
Paso 5: Ajuste Final en el Archivo de Enlaces (enlaces.php)
Para que la redirección funcione, necesitamos que nuestro sistema de "enlaces" (o controlador de vistas) reconozca la nueva acción fallo y muestre la vista correcta.
Asumiendo que tienes un archivo enlaces.php que carga las páginas según $_GET["action"], debes asegurarte de incluir el caso para "fallo".
<?php // enlaces.php (fragmento) $pagina = $_GET["action"] ?? "ingresar"; // Si no hay action, va a ingresar switch ($pagina) { case 'usuarios': include 'vistas/usuarios.php'; // La página a donde va si el login es exitoso break; case 'fallo': include 'vistas/ingresar.php'; // Volvemos a la página de login break; case 'registro': include 'vistas/registro.php'; break; // ... otros casos default: include 'vistas/ingresar.php'; } ?>
Explicación:
Cuando el login es exitoso, el
headernos manda aindex.php?action=usuarios. Elenlaces.phpcarga la página de usuarios.Cuando el login falla, el
headernos manda aindex.php?action=fallo. Elenlaces.phpvuelve a cargaringresar.php. Y como eningresar.phptenemos el código que mira si$_GET["action"] == "fallo", mostrará el mensaje "Fallo al ingresar".
Resumen y Conceptos Clave
PDO y
SELECT: Para leer datos de la BD usamosSELECTconprepare(),bindParam()yexecute().fetch(): Método de PDO que devuelve una sola fila de resultados como un arreglo. Si no hay resultados, devuelvefalse.Flujo del Login:
Vista (Formulario): Captura los datos del usuario.
Controlador: Recibe los datos, los envía al Modelo y toma decisiones.
Modelo: Ejecuta la consulta SQL y devuelve el resultado.
Errores como Maestros: Aprendimos a interpretar un
var_dump()para entender la estructura de los datos que devuelve la BD y a usaris_array()para validar si un usuario existe.
¡Y así es como hemos creado un sistema de login funcional leyendo datos con PDO! En el próximo tutorial, veremos cómo mejorar la seguridad manejando sesiones y encriptando contraseñas.
Comentarios
Publicar un comentario