En el desarrollo web, la creación de un espacio donde los visitantes puedan dejar comentarios es una excelente manera de fomentar la interacción. Este tutorial te guiará a través del desarrollo de un Libro de Visitas en PHP y MySQL, cubriendo desde la configuración de la base de datos hasta la implementación de un frontend responsivo y atractivo.
Te recomiendo que revises mi blog entero, actualmente tengo más de 150 aplicaciones de libre distribución que te podrían servir, aplicaciones en PHP, Javascript, Python, Node JS, así como tutoriales sobre desarrollo web.
Video Explicativo
Estructura y Funcionamiento del Proyecto
Nuestro proyecto se organizará de la siguiente manera:
<span class="line"><span style="color: #D8DEE9">libro</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">de</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">visitas</span><span style="color: #81A1C1">/</span></span>
<span class="line"><span style="color: #D8DEE9FF">│</span></span>
<span class="line"><span style="color: #D8DEE9FF">├── </span><span style="color: #D8DEE9">css</span><span style="color: #81A1C1">/</span></span>
<span class="line"><span style="color: #D8DEE9FF">│ └── </span><span style="color: #D8DEE9">estilo</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">css</span><span style="color: #D8DEE9FF"> # </span><span style="color: #D8DEE9">Estilos</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">responsivos</span></span>
<span class="line"><span style="color: #D8DEE9FF">│</span></span>
<span class="line"><span style="color: #D8DEE9FF">├── </span><span style="color: #D8DEE9">js</span><span style="color: #81A1C1">/</span></span>
<span class="line"><span style="color: #D8DEE9FF">│ └── </span><span style="color: #D8DEE9">scripts</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">js</span><span style="color: #D8DEE9FF"> # </span><span style="color: #D8DEE9">Mejoras</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">interactividad</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">opcional</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">│</span></span>
<span class="line"><span style="color: #D8DEE9FF">├── </span><span style="color: #D8DEE9">index</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">php</span><span style="color: #D8DEE9FF"> # </span><span style="color: #D8DEE9">Página</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">principal</span></span>
<span class="line"><span style="color: #D8DEE9FF">├── </span><span style="color: #D8DEE9">guardar_visita</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">php</span><span style="color: #D8DEE9FF"> # </span><span style="color: #D8DEE9">Procesamiento</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">de</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">entradas</span></span>
<span class="line"><span style="color: #D8DEE9FF">│</span></span>
<span class="line"><span style="color: #D8DEE9FF">└── </span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">htaccess</span><span style="color: #D8DEE9FF"> # </span><span style="color: #D8DEE9">Configuraciones</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">del</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">servidor</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">opcional</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>Desarrollo del Proyecto
- Configuración de la Base de Datos: Comenzamos creando una base de datos
libro_visitasy una tablavisitaspara almacenar los mensajes de los usuarios.
<span class="line"><span style="color: #D8DEE9">CREATE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">TABLE</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">visitas</span><span style="color: #D8DEE9FF"> (</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">id</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">INT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AUTO_INCREMENT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">PRIMARY</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">KEY</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">nombre</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">VARCHAR</span><span style="color: #D8DEE9FF">(</span><span style="color: #B48EAD">255</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">NOT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mensaje</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">TEXT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NOT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">fecha</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">TIMESTAMP</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DEFAULT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CURRENT_TIMESTAMP</span></span>
<span class="line"><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>Backend con PHP:
index.php: Este archivo será el corazón de nuestro libro de visitas. Mostrará un formulario para que los visitantes puedan dejar su nombre y mensaje, además de listar todos los mensajes previos.
<span class="line"><span style="color: #81A1C1"><?</span><span style="color: #D8DEE9">php</span></span>
<span class="line"><span style="color: #616E88">// Conexión a la base de datos (reemplazar con tus propios detalles de conexión)</span></span>
<span class="line"><span style="color: #D8DEE9">$host</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">localhost</span><span style="color: #ECEFF4">'</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #D8DEE9">$dbname</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">libro_visitas</span><span style="color: #ECEFF4">'</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #D8DEE9">$user</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">root</span><span style="color: #ECEFF4">'</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #D8DEE9">$password</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">''</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #D8DEE9">$dsn</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">mysql:host=$host;dbname=$dbname;charset=UTF8</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">try</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$pdo</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">PDO</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">$dsn</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$user</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$password</span><span style="color: #D8DEE9FF">);</span></span>
<span class="line"><span style="color: #D8DEE9FF"> $pdo-></span><span style="color: #88C0D0">setAttribute</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">PDO</span><span style="color: #81A1C1">::</span><span style="color: #D8DEE9FF">ATTR_ERRMODE</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">PDO</span><span style="color: #81A1C1">::</span><span style="color: #D8DEE9FF">ERRMODE_EXCEPTION</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">catch</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">PDOException</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$e</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> echo </span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">Error de conexión: </span><span style="color: #ECEFF4">"</span><span style="color: #88C0D0"> . $e->getMessage();</span></span>
<span class="line"><span style="color: #88C0D0"> exit;</span></span>
<span class="line"><span style="color: #88C0D0">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Recuperar las visitas de la base de datos</span></span>
<span class="line"><span style="color: #88C0D0">$sql = </span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">SELECT nombre, mensaje, DATE_FORMAT(fecha, '%d/%m/%Y %H:%i') AS fecha_formateada FROM visitas ORDER BY fecha DESC</span><span style="color: #ECEFF4">"</span><span style="color: #88C0D0">;</span></span>
<span class="line"><span style="color: #88C0D0">$visitas = $pdo->query($sql)->fetchAll(PDO</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF">:</span><span style="color: #D8DEE9">FETCH_ASSOC</span><span style="color: #D8DEE9FF">);</span></span>
<span class="line"><span style="color: #81A1C1">?></span></span>
<span class="line"><span style="color: #81A1C1"><!</span><span style="color: #D8DEE9">DOCTYPE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">html</span><span style="color: #81A1C1">></span></span>
<span class="line"><span style="color: #81A1C1"><html</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">lang</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">es</span><span style="color: #ECEFF4">"</span><span style="color: #81A1C1">></span></span>
<span class="line"><span style="color: #81A1C1"><head></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><meta</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">charset</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">UTF-8</span><span style="color: #ECEFF4">"</span><span style="color: #81A1C1">></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><meta</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">name</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">viewport</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">content</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">width=device-width, initial-scale=1.0</span><span style="color: #ECEFF4">"</span><span style="color: #81A1C1">></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><title></span><span style="color: #D8DEE9FF">Libro de Visitas</span><span style="color: #81A1C1"></title></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><link</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">rel</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">stylesheet</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">href</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">css/estilo.css</span><span style="color: #ECEFF4">"</span><span style="color: #81A1C1">></span></span>
<span class="line"><span style="color: #81A1C1"></head></span></span>
<span class="line"><span style="color: #81A1C1"><body></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><h1></span><span style="color: #D8DEE9FF">Libro de Visitas</span><span style="color: #81A1C1"></h1></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><form</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">action</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">guardar_visita.php</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">method</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">post</span><span style="color: #ECEFF4">"</span><span style="color: #81A1C1">></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><input</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">type</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">text</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">name</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">nombre</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">placeholder</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">Tu nombre</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">required</span><span style="color: #81A1C1">></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><textarea</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">name</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">mensaje</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">placeholder</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">Tu mensaje</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">required</span><span style="color: #81A1C1">></textarea></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><button</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">type</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">submit</span><span style="color: #ECEFF4">"</span><span style="color: #81A1C1">></span><span style="color: #D8DEE9FF">Enviar</span><span style="color: #81A1C1"></button></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"></form></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><h2></span><span style="color: #D8DEE9FF">Mensajes Anteriores</span><span style="color: #81A1C1"></h2></span></span>
<span class="line"><span style="color: #D8DEE9FF"> <?php if ($visitas): ?></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><ul></span></span>
<span class="line"><span style="color: #D8DEE9FF"> <?php foreach ($visitas as $visita): ?></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><li></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><strong></span><span style="color: #D8DEE9FF"><?= htmlspecialchars($visita['nombre'], ENT_QUOTES, 'UTF-8') ?>:</span><span style="color: #81A1C1"></strong></span></span>
<span class="line"><span style="color: #D8DEE9FF"> <?= nl2br(htmlspecialchars($visita['mensaje'], ENT_QUOTES, 'UTF-8')) ?></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><em></span><span style="color: #D8DEE9FF">(<?= $visita['fecha_formateada'] ?>)</span><span style="color: #81A1C1"></em></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"></li></span></span>
<span class="line"><span style="color: #D8DEE9FF"> <?php endforeach; ?></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"></ul></span></span>
<span class="line"><span style="color: #D8DEE9FF"> <?php else: ?></span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1"><p></span><span style="color: #D8DEE9FF">No hay mensajes aún.</span><span style="color: #81A1C1"></p></span></span>
<span class="line"><span style="color: #D8DEE9FF"> <?php endif; ?></span></span>
<span class="line"><span style="color: #81A1C1"></body></span></span>
<span class="line"><span style="color: #81A1C1"></html></span></span>
<span class="line"></span>guardar_visita.php: Procesa la entrada del formulario, insertando los datos en la base de datos.
<span class="line"><span style="color: #81A1C1"><?</span><span style="color: #D8DEE9">php</span></span>
<span class="line"><span style="color: #616E88">// Conexión a la base de datos</span></span>
<span class="line"><span style="color: #D8DEE9">$host</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">localhost</span><span style="color: #ECEFF4">'</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #D8DEE9">$dbname</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">libro_visitas</span><span style="color: #ECEFF4">'</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #D8DEE9">$user</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">root</span><span style="color: #ECEFF4">'</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #D8DEE9">$password</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">''</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #D8DEE9">$dsn</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">mysql:host=$host;dbname=$dbname;charset=UTF8</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">try</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$pdo</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">PDO</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">$dsn</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$user</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$password</span><span style="color: #D8DEE9FF">);</span></span>
<span class="line"><span style="color: #D8DEE9FF"> $pdo-></span><span style="color: #88C0D0">setAttribute</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">PDO</span><span style="color: #81A1C1">::</span><span style="color: #D8DEE9FF">ATTR_ERRMODE</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">PDO</span><span style="color: #81A1C1">::</span><span style="color: #D8DEE9FF">ERRMODE_EXCEPTION</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">catch</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">PDOException</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$e</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> echo </span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">Error de conexión: </span><span style="color: #ECEFF4">"</span><span style="color: #88C0D0"> . $e->getMessage();</span></span>
<span class="line"><span style="color: #88C0D0"> exit;</span></span>
<span class="line"><span style="color: #88C0D0">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Validar y sanitizar la entrada</span></span>
<span class="line"><span style="color: #88C0D0">$nombre = filter_input(INPUT_POST, </span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">nombre</span><span style="color: #ECEFF4">'</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> FILTER_SANITIZE_STRING);</span></span>
<span class="line"><span style="color: #D8DEE9">$mensaje</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">filter_input</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">INPUT_POST</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">mensaje</span><span style="color: #ECEFF4">'</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">FILTER_SANITIZE_STRING</span><span style="color: #D8DEE9FF">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Verificar que el nombre y el mensaje no estén vacíos</span></span>
<span class="line"><span style="color: #88C0D0">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">empty</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">$nombre</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> || </span><span style="color: #88C0D0">empty</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">$mensaje</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">echo</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">El nombre y el mensaje son obligatorios.</span><span style="color: #ECEFF4">"</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">exit</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Preparar la consulta SQL para insertar la visita</span></span>
<span class="line"><span style="color: #D8DEE9">$sql</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">INSERT INTO visitas (nombre, mensaje, fecha) VALUES (:nombre, :mensaje, NOW())</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #D8DEE9">$stmt</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$pdo</span><span style="color: #81A1C1">-></span><span style="color: #88C0D0">prepare</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">$sql</span><span style="color: #D8DEE9FF">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Vincular los parámetros y ejecutar la consulta</span></span>
<span class="line"><span style="color: #D8DEE9FF">$stmt-></span><span style="color: #88C0D0">bindParam</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">:nombre</span><span style="color: #ECEFF4">'</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$nombre</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">PDO</span><span style="color: #81A1C1">::</span><span style="color: #D8DEE9FF">PARAM_STR</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">$stmt-></span><span style="color: #88C0D0">bindParam</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">:mensaje</span><span style="color: #ECEFF4">'</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$mensaje</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">PDO</span><span style="color: #81A1C1">::</span><span style="color: #D8DEE9FF">PARAM_STR</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">try </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$stmt</span><span style="color: #81A1C1">-></span><span style="color: #88C0D0">execute</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4"> </span><span style="color: #616E88">// Redireccionar de vuelta a la página principal</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">header</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">Location: index.php</span><span style="color: #ECEFF4">'</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> catch (PDOException $e) {</span></span>
<span class="line"><span style="color: #D8DEE9FF"> echo "Error al guardar la visita: " . $e-></span><span style="color: #88C0D0">getMessage</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>Frontend y Estilos Responsivos:
css/estilo.css: Define los estilos del libro de visitas, asegurando que se vea bien en dispositivos móviles y de escritorio.
<span class="line"><span style="color: #D8DEE9FF">:</span><span style="color: #D8DEE9">root</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9">color</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">primario</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> #007</span><span style="color: #D8DEE9">bff</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9">color</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">secundario</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> #6</span><span style="color: #D8DEE9">c757d</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9">color</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">fondo</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> #</span><span style="color: #D8DEE9">f8f9fa</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9">color</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">texto</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> #</span><span style="color: #B48EAD">212529</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/* Restablecer algunos estilos por defecto y establecer estilos base */</span></span>
<span class="line"><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">margin</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">padding</span><span style="color: #D8DEE9FF">: </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">box</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">sizing</span><span style="color: #D8DEE9FF">: </span><span style="color: #D8DEE9">border</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">box</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">body</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">font</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">family</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">Segoe UI</span><span style="color: #ECEFF4">'</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Tahoma</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Geneva</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Verdana</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sans</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">serif</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">background</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">color</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">var</span><span style="color: #D8DEE9FF">(--</span><span style="color: #D8DEE9">color</span><span style="color: #D8DEE9FF">-fondo)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> color</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">var</span><span style="color: #D8DEE9FF">(--</span><span style="color: #D8DEE9">color</span><span style="color: #D8DEE9FF">-texto)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">line</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">height</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1.6</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> padding</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 20</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">container</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">max</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">width</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 800</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> margin</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">auto</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> overflow</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">hidden</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> padding</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF"> 20</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">header</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> background</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">var</span><span style="color: #D8DEE9FF">(--</span><span style="color: #D8DEE9">color</span><span style="color: #D8DEE9FF">-primario)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> color</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> #</span><span style="color: #D8DEE9">fff</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">padding</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">top</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 30</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">min</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">height</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 70</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">border</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">bottom</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 3</span><span style="color: #D8DEE9">px</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">solid</span><span style="color: #D8DEE9FF"> #</span><span style="color: #88C0D0">darker</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">var</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9">color</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">primario</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10</span><span style="color: #81A1C1">%</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">header</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">h1</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">text</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">align</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">center</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">form</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">margin</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">top</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 20</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> background</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> #</span><span style="color: #D8DEE9">fff</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> padding</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 20</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">border</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">radius</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 8</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">input</span><span style="color: #D8DEE9FF">[</span><span style="color: #D8DEE9">type</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">text</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF">]</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9">textarea</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> width</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">100</span><span style="color: #81A1C1">%;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> padding</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 10</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">margin</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">top</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 10</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> border</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 1</span><span style="color: #D8DEE9">px</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">solid</span><span style="color: #D8DEE9FF"> #</span><span style="color: #D8DEE9">ccc</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">border</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">radius</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 5</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">button</span><span style="color: #D8DEE9FF">[</span><span style="color: #D8DEE9">type</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">submit</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF">] </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> display</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">block</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> width</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">100</span><span style="color: #81A1C1">%;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> padding</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 10</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">margin</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">top</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 20</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> background</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">var</span><span style="color: #D8DEE9FF">(--</span><span style="color: #D8DEE9">color</span><span style="color: #D8DEE9FF">-primario)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> color</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> #</span><span style="color: #D8DEE9">fff</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> border</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> cursor</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pointer</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">border</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">radius</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 5</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">button</span><span style="color: #D8DEE9FF">[</span><span style="color: #D8DEE9">type</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">submit</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF">]:</span><span style="color: #D8DEE9">hover</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> background</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> #0056</span><span style="color: #D8DEE9">b3</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">ul</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">list</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">style</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">none</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">margin</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">top</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 20</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">li</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> background</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> #</span><span style="color: #D8DEE9">fff</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> padding</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 10</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">margin</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">bottom</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 10</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">border</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">radius</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> 5</span><span style="color: #D8DEE9">px</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D08770">@media</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">screen</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">and</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">max</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">width</span><span style="color: #D8DEE9FF">: 768</span><span style="color: #D8DEE9">px</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">header</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">h1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">form</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ul</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> width</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">90</span><span style="color: #81A1C1">%;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">margin</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">left</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">auto</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">margin</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">right</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">auto</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/* Colores adicionales y efectos hover podrían ser agregados aquí */</span></span>
<span class="line"></span>js/scripts.js (Opcional): Añade interactividad avanzada, como validaciones del lado del cliente o envíos de formulario asincrónicos.
<span class="line"><span style="color: #D8DEE9">document</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">addEventListener</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">DOMContentLoaded</span><span style="color: #ECEFF4">'</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">function</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">form</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">document</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">querySelector</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">form</span><span style="color: #ECEFF4">'</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">form</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">addEventListener</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">submit</span><span style="color: #ECEFF4">'</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">function</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">e</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">let</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">hasError</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false;</span></span>
<span class="line"><span style="color: #ECEFF4"> </span><span style="color: #616E88">// Ejemplo de validación simple</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">document</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">querySelector</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">input[name="nombre"]</span><span style="color: #ECEFF4">'</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">value</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">trim</span><span style="color: #D8DEE9FF">() </span><span style="color: #81A1C1">===</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">''</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">alert</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">Por favor, ingresa tu nombre.</span><span style="color: #ECEFF4">'</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">hasError</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">true;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">document</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">querySelector</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">textarea[name="mensaje"]</span><span style="color: #ECEFF4">'</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">value</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">trim</span><span style="color: #D8DEE9FF">() </span><span style="color: #81A1C1">===</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">''</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">alert</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">'</span><span style="color: #A3BE8C">Por favor, ingresa un mensaje.</span><span style="color: #ECEFF4">'</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">hasError</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">true;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">hasError</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">e</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">preventDefault</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// Previene que el formulario se envíe</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>.htaccess(Opcional): Puede contener configuraciones específicas del servidor, como URLs amigables.
Implementación y Funcionalidades Clave
- Validación y Seguridad: Es fundamental validar las entradas del usuario tanto en el cliente (JavaScript) como en el servidor (PHP) para evitar inyecciones SQL y ataques XSS.
- Estilos Responsivos: Usamos CSS para garantizar que nuestro libro de visitas se vea bien en cualquier dispositivo, mejorando la experiencia del usuario.
Repositorio del Sistema
Conclusión
Crear un Libro de Visitas con PHP y MySQL es un proyecto enriquecedor que no solo mejora tus habilidades de desarrollo web sino que también te permite experimentar con aspectos críticos como la seguridad de la aplicación, el diseño responsivo, y la interacción del usuario. A través de este proyecto, no solo has aprendido a trabajar con tecnologías del lado del servidor y del cliente sino también a pensar en cómo estructurar aplicaciones web de manera efectiva y atractiva.
Este tutorial es solo el principio. A medida que tus habilidades crezcan, podrás añadir más características, como autenticación de usuarios, moderación de comentarios, o incluso integración con redes sociales. El mundo del desarrollo web está lleno de posibilidades, y proyectos prácticos como este son el primer paso hacia la maestría en la creación de aplicaciones web dinámicas y atractivas.
Para desarrollos a medida me puedes contactar en el siguiente enlace de contacto