Velocidad EE3

Velocidad EE3

Estimación del tiempo de carga basada en el peso de la página y el ancho de banda. Incluye aproximación de latencia y rendimiento real.

Abrir Velocidad-ee3

Concepto general

Cuando hablamos de tiempo de carga de una página web, lo que realmente medimos es cuánto tarda en descargarse y mostrarse en el navegador. Ese tiempo depende de varios factores:

  1. Peso de la página (MB)
    • Es el tamaño total de todos los recursos: HTML, CSS, JavaScript, imágenes, fuentes, etc.
    • Cuanto más grande sea, más datos hay que transferir.
  2. Ancho de banda (Mbps)
    • Es la velocidad de la conexión de red disponible.
    • Se mide en megabits por segundo (ojo: 1 byte = 8 bits).
    • A mayor ancho de banda, más rápido se transfieren los datos.

Fórmula básica

El tiempo de descarga puro se calcula así:

Tiempo de descarga (s)=Peso de la paˊgina (MB)×8Ancho de banda (Mbps)

Ejemplo:

  • Página de 2 MB
  • Conexión de 20 Mbps

2×820=0.8 segundos

Latencia

  • La latencia es el retraso que introduce la red en cada petición (RTT: Round Trip Time).
  • Aunque tengas mucho ancho de banda, si la latencia es alta (ej. 200 ms en redes móviles), cada recurso tarda más en empezar a descargarse.
  • Por eso se añade una aproximación de latencia al cálculo.

Rendimiento real

En la práctica, el tiempo de carga no es solo descarga + latencia. También influyen:

  • Número de peticiones (cada imagen, script, fuente es una petición).
  • Conexiones paralelas (los navegadores abren varias conexiones a la vez, pero no infinitas).
  • Protocolos (HTTP/2 y HTTP/3 reducen overhead).
  • Eficiencia de red (compresión, caché, TCP slow-start).

Por eso se aplica un factor de eficiencia (ej. 85%) para acercarse más a la realidad.

El tamaño total de una página web en MB se mide sumando el peso de todos los recursos que el navegador descarga para mostrarla. Te lo explico en detalle:

🔍 Qué se mide exactamente

  • HTML principal (el documento base).
  • CSS (hojas de estilo).
  • JavaScript (scripts).
  • Imágenes (PNG, JPG, SVG, WebP, etc.).
  • Fuentes web (tipografías).
  • Otros recursos (videos, audios, iconos, etc.).

Cada archivo tiene un tamaño en bytes. La suma de todos esos bytes se convierte a megabytes (MB):

1 MB=1024×1024 bytes≈1,048,576 bytes

Cómo medirlo en la práctica

  1. Herramientas del navegador (DevTools)
    • Abres la página en Chrome/Firefox.
    • Pulsa F12 → pestaña Network.
    • Recarga la página.
    • En la parte inferior verás el Total transferido (suma de todos los recursos).
    • Ese número lo conviertes a MB.
  2. Servicios online
    • Herramientas como GTmetrixPingdom Tools o WebPageTest te dan el tamaño total de la página y un desglose por tipo de recurso.
  3. Línea de comandos (para desarrolladores)
    • Usando wget o curl puedes descargar la página y medir el tamaño de los archivos.
    • Ejemplo: wget --page-requisites --span-hosts URL descarga todo y luego puedes calcular el peso con du -sh.

Ejemplo real

  • Página con:
    • HTML: 100 KB
    • CSS: 200 KB
    • JS: 1.5 MB
    • Imágenes: 3 MB
    • Fuentes: 500 KB

Total = 5.3 MB

Valorar un Dominio

Calculadora de Valor de Dominio

Calculadora de Valor de Dominio

← Volver al Inicio

Estime el valor potencial de su dominio basándose en criterios clave de mercado.

Este campo es solo informativo para la etiqueta de resultado.

Los dominios antiguos tienen mayor confianza y prestigio.

Cuanto más corto (hasta un límite), mayor valor.

El TLD y la calidad del nombre afectan la percepción.

5

Una marca memorable vale mucho en el mercado.

© 2024 Calculadora de Valor de Dominio. Desarrollado con fines educativos.

Login HTML

Aprende a crear una estructura de registro de miembros para tu página web. Te explico como hacerlo en HTML, CSS y JS. Luego lee el artículo hasta el final para la verificación del usuario, la creación de la base de datos, y el estilo de tus páginas de registro, login, y verificación de email.

Te dejo una estructura completa con HTML + CSS + JS (fetch a endpoints) que puedes conectar a tu backend (WordPress o API propia). Si quieres mockear sin servidor, también incluyo una variante con localStorage.

Estructura de archivos HTML para login, registro, verificación y perfil

Árbol de proyecto

  • /assets/
    • styles.css
    • auth.js
  • login.html
  • register.html
  • verify.html
  • profile.html
  • reset.html

HTML de cada página

Login

html

<!-- login.html -->
<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <title>Acceder</title>
  <link rel="stylesheet" href="assets/styles.css">
</head>
<body>
  <main class="card">
    <h1>Acceder</h1>
    <form id="login-form">
      <label>Correo
        <input type="email" name="email" required>
      </label>
      <label>Contraseña
        <input type="password" name="password" required>
      </label>
      <button type="submit">Entrar</button>
      <p class="hint">
        <a href="reset.html">¿Olvidaste tu contraseña?</a> ·
        <a href="register.html">Crear cuenta</a>
      </p>
      <p class="msg" id="login-msg"></p>
    </form>
  </main>
  <script src="assets/auth.js"></script>
  <script>
    bindLogin({
      onSuccess: () => location.href = 'profile.html',
      onError: (msg) => showMsg('login-msg', msg)
    });
  </script>
</body>
</html>

Registro

html

<!-- register.html -->
<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <title>Registrarse</title>
  <link rel="stylesheet" href="assets/styles.css">
</head>
<body>
  <main class="card">
    <h1>Crear cuenta</h1>
    <form id="register-form">
      <label>Nombre
        <input type="text" name="name" required>
      </label>
      <label>Correo
        <input type="email" name="email" required>
      </label>
      <label>Contraseña
        <input type="password" name="password" required minlength="8">
      </label>
      <button type="submit">Registrarse</button>
      <p class="msg" id="register-msg"></p>
      <p class="hint"><a href="login.html">¿Ya tienes cuenta? Accede</a></p>
    </form>
  </main>
  <script src="assets/auth.js"></script>
  <script>
    bindRegister({
      // Tras registro, muestra mensaje y sugiere verificación
      onSuccess: (email) => {
        showMsg('register-msg', 'Registro realizado. Revisa tu correo para verificar la cuenta.');
        // Opcional: redirigir a verify.html con token en query si tu backend lo hace automático
        // location.href = 'verify.html?email=' + encodeURIComponent(email);
      },
      onError: (msg) => showMsg('register-msg', msg)
    });
  </script>
</body>
</html>

Verificación por correo

html

<!-- verify.html -->
<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <title>Verificar cuenta</title>
  <link rel="stylesheet" href="assets/styles.css">
</head>
<body>
  <main class="card">
    <h1>Verificar cuenta</h1>
    <p>Si llegaste aquí desde tu correo, el enlace incluirá un token.</p>
    <form id="verify-form">
      <label>Token de verificación
        <input type="text" name="token" required>
      </label>
      <button type="submit">Verificar</button>
      <p class="msg" id="verify-msg"></p>
    </form>
  </main>
  <script src="assets/auth.js"></script>
  <script>
    // Si viene ?token= en la URL, precarga
    const params = new URLSearchParams(location.search);
    const token = params.get('token');
    if (token) document.querySelector('[name="token"]').value = token;

    bindVerify({
      onSuccess: () => {
        showMsg('verify-msg', 'Cuenta verificada. Ya puedes acceder.');
        setTimeout(() => location.href = 'login.html', 1200);
      },
      onError: (msg) => showMsg('verify-msg', msg)
    });
  </script>
</body>
</html>

Perfil de usuario

html

<!-- profile.html -->
<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <title>Perfil</title>
  <link rel="stylesheet" href="assets/styles.css">
</head>
<body>
  <main class="card">
    <h1>Tu perfil</h1>
    <section id="profile">
      <p><strong>Nombre:</strong> <span id="pf-name">—</span></p>
      <p><strong>Correo:</strong> <span id="pf-email">—</span></p>
      <p><strong>Estado:</strong> <span id="pf-status">—</span></p>
    </section>
    <hr>
    <form id="update-form">
      <h2>Actualizar perfil</h2>
      <label>Nombre
        <input type="text" name="name" required>
      </label>
      <button type="submit">Guardar</button>
      <p class="msg" id="update-msg"></p>
    </form>
    <button id="logout">Cerrar sesión</button>
  </main>
  <script src="assets/auth.js"></script>
  <script>
    requireAuth({
      onUnauthorized: () => location.href = 'login.html'
    });
    loadProfile({
      onData: (u) => {
        document.getElementById('pf-name').textContent = u.name;
        document.getElementById('pf-email').textContent = u.email;
        document.getElementById('pf-status').textContent = u.verified ? 'Verificada' : 'Pendiente';
        document.querySelector('#update-form [name="name"]').value = u.name;
      }
    });
    bindProfileUpdate({
      onSuccess: (u) => showMsg('update-msg', 'Perfil actualizado.'),
      onError: (msg) => showMsg('update-msg', msg)
    });
    bindLogout(() => location.href = 'login.html');
  </script>
</body>
</html>

Recuperación de contraseña

html

<!-- reset.html -->
<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <title>Recuperar contraseña</title>
  <link rel="stylesheet" href="assets/styles.css">
</head>
<body>
  <main class="card">
    <h1>Recuperar contraseña</h1>
    <form id="reset-form">
      <label>Correo
        <input type="email" name="email" required>
      </label>
      <button type="submit">Enviar enlace</button>
      <p class="msg" id="reset-msg"></p>
    </form>
  </main>
  <script src="assets/auth.js"></script>
  <script>
    bindReset({
      onSuccess: () => showMsg('reset-msg', 'Te hemos enviado un correo con instrucciones.'),
      onError: (msg) => showMsg('reset-msg', msg)
    });
  </script>
</body>
</html>

CSS base compartido

css

/* assets/styles.css */
:root {
  color-scheme: light dark;
  --bg: #0b0c10;
  --card: #1f2833;
  --text: #c5c6c7;
  --accent: #66fcf1;
  --muted: #7a7d80;
}

* { box-sizing: border-box; }
body {
  margin: 0; font-family: system-ui, sans-serif;
  display: grid; place-items: center; min-height: 100vh;
  background: var(--bg); color: var(--text);
}
.card {
  width: min(600px, 92vw); background: var(--card);
  padding: 24px; border-radius: 14px;
  box-shadow: 0 10px 30px rgba(0,0,0,.35);
}
h1, h2 { margin: 0 0 12px; color: var(--accent); }
label { display: grid; gap: 6px; margin: 12px 0; }
input, button {
  padding: 10px 12px; border-radius: 8px; border: 1px solid #2b3440;
  background: #0f1622; color: var(--text);
}
button {
  background: var(--accent); color: #081217; border: none; font-weight: 700; cursor: pointer;
}
button:hover { filter: brightness(1.08); }
.hint { color: var(--muted); margin-top: 12px; }
.msg { margin-top: 10px; min-height: 20px; }
hr { border: none; border-top: 1px solid #2b3440; margin: 18px 0; }

JS de autenticación (API real o mock)

Versión con API real (recomendado)

Define endpoints en tu backend:

  • POST /api/auth/login
  • POST /api/auth/register
  • POST /api/auth/verify
  • POST /api/auth/reset
  • GET /api/user/me
  • PATCH /api/user/me

El JS usa JWT en localStorage y redirecciones.

js

// assets/auth.js
const API = '/api';
const TOKEN_KEY = 'auth_token';

function showMsg(id, msg) {
  const el = document.getElementById(id);
  if (el) el.textContent = msg;
}

function setToken(t) { localStorage.setItem(TOKEN_KEY, t); }
function getToken() { return localStorage.getItem(TOKEN_KEY); }
function clearToken() { localStorage.removeItem(TOKEN_KEY); }

async function request(path, opts = {}) {
  const headers = { 'Content-Type': 'application/json', ...(opts.headers || {}) };
  const token = getToken();
  if (token) headers.Authorization = `Bearer ${token}`;
  const res = await fetch(API + path, { ...opts, headers });
  const data = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(data.message || 'Error de servidor');
  return data;
}

function bindLogin({ onSuccess, onError }) {
  document.getElementById('login-form').addEventListener('submit', async e => {
    e.preventDefault();
    const f = e.target;
    try {
      const data = await request('/auth/login', {
        method: 'POST',
        body: JSON.stringify({ email: f.email.value, password: f.password.value })
      });
      setToken(data.token);
      onSuccess?.(data);
    } catch (err) {
      onError?.(err.message);
    }
  });
}

function bindRegister({ onSuccess, onError }) {
  document.getElementById('register-form').addEventListener('submit', async e => {
    e.preventDefault();
    const f = e.target;
    try {
      const data = await request('/auth/register', {
        method: 'POST',
        body: JSON.stringify({ name: f.name.value, email: f.email.value, password: f.password.value })
      });
      onSuccess?.(f.email.value, data);
    } catch (err) {
      onError?.(err.message);
    }
  });
}

function bindVerify({ onSuccess, onError }) {
  document.getElementById('verify-form').addEventListener('submit', async e => {
    e.preventDefault();
    const f = e.target;
    try {
      await request('/auth/verify', {
        method: 'POST',
        body: JSON.stringify({ token: f.token.value })
      });
      onSuccess?.();
    } catch (err) {
      onError?.(err.message);
    }
  });
}

function bindReset({ onSuccess, onError }) {
  document.getElementById('reset-form').addEventListener('submit', async e => {
    e.preventDefault();
    const f = e.target;
    try {
      await request('/auth/reset', {
        method: 'POST',
        body: JSON.stringify({ email: f.email.value })
      });
      onSuccess?.();
    } catch (err) {
      onError?.(err.message);
    }
  });
}

function requireAuth({ onUnauthorized }) {
  const token = getToken();
  if (!token) return onUnauthorized?.();
}

async function loadProfile({ onData }) {
  const data = await request('/user/me', { method: 'GET' });
  onData?.(data.user);
}

function bindProfileUpdate({ onSuccess, onError }) {
  document.getElementById('update-form').addEventListener('submit', async e => {
    e.preventDefault();
    const f = e.target;
    try {
      const data = await request('/user/me', {
        method: 'PATCH',
        body: JSON.stringify({ name: f.name.value })
      });
      onSuccess?.(data.user);
    } catch (err) {
      onError?.(err.message);
    }
  });
}

function bindLogout(cb) {
  document.getElementById('logout').addEventListener('click', () => {
    clearToken(); cb?.();
  });
}

Versión sin backend (mock rápido con localStorage)

Útil para validar flujo visual. No es seguro; solo para prototipo.

js

// assets/auth.js (mock)
const TOKEN_KEY = 'auth_token';
const USERS_KEY = 'users';

function showMsg(id, msg) { const el = document.getElementById(id); if (el) el.textContent = msg; }
function setToken(t) { localStorage.setItem(TOKEN_KEY, t); }
function getToken() { return localStorage.getItem(TOKEN_KEY); }
function clearToken() { localStorage.removeItem(TOKEN_KEY); }

function getUsers() { return JSON.parse(localStorage.getItem(USERS_KEY) || '[]'); }
function setUsers(u) { localStorage.setItem(USERS_KEY, JSON.stringify(u)); }
function uid() { return Math.random().toString(36).slice(2); }

function bindLogin({ onSuccess, onError }) {
  document.getElementById('login-form').addEventListener('submit', e => {
    e.preventDefault(); const f = e.target;
    const users = getUsers();
    const u = users.find(x => x.email === f.email.value);
    if (!u) return onError?.('No existe ese correo.');
    if (!u.verified) return onError?.('Cuenta no verificada. Revisa tu correo.');
    if (u.password !== f.password.value) return onError?.('Contraseña incorrecta.');
    setToken(u.id); onSuccess?.(u);
  });
}

function bindRegister({ onSuccess, onError }) {
  document.getElementById('register-form').addEventListener('submit', e => {
    e.preventDefault(); const f = e.target;
    const users = getUsers();
    if (users.some(x => x.email === f.email.value)) return onError?.('Ese correo ya existe.');
    const token = uid();
    const u = { id: uid(), email: f.email.value, name: f.name.value, password: f.password.value, verified: false, verifyToken: token };
    users.push(u); setUsers(users);
    // Simula envío de email: muestra token
    onSuccess?.(u.email);
    alert('Token de verificación (simulado): ' + token);
  });
}

function bindVerify({ onSuccess, onError }) {
  document.getElementById('verify-form').addEventListener('submit', e => {
    e.preventDefault(); const f = e.target;
    const users = getUsers();
    const u = users.find(x => x.verifyToken === f.token.value);
    if (!u) return onError?.('Token inválido.');
    u.verified = true; setUsers(users);
    onSuccess?.();
  });
}

function bindReset({ onSuccess, onError }) {
  document.getElementById('reset-form').addEventListener('submit', e => {
    e.preventDefault(); const f = e.target;
    const users = getUsers();
    const u = users.find(x => x.email === f.email.value);
    if (!u) return onError?.('No existe ese correo.');
    const newPass = prompt('Introduce nueva contraseña (simulación):');
    if (!newPass) return onError?.('Operación cancelada.');
    u.password = newPass; setUsers(users);
    onSuccess?.();
  });
}

function requireAuth({ onUnauthorized }) {
  const token = getToken();
  if (!token) return onUnauthorized?.();
}

function loadProfile({ onData }) {
  const users = getUsers();
  const u = users.find(x => x.id === getToken());
  if (!u) return onData?.({ name: '', email: '', verified: false });
  onData?.(u);
}

function bindProfileUpdate({ onSuccess, onError }) {
  document.getElementById('update-form').addEventListener('submit', e => {
    e.preventDefault(); const f = e.target;
    const users = getUsers();
    const u = users.find(x => x.id === getToken());
    if (!u) return onError?.('Sesión no válida.');
    u.name = f.name.value; setUsers(users);
    onSuccess?.(u);
  });
}

function bindLogout(cb) {
  document.getElementById('logout').addEventListener('click', () => { clearToken(); cb?.(); });
}

Flujo de navegación

  1. Registro → guarda usuario y envía correo con token.
  2. Verificación → el usuario hace clic en el enlace con token (o lo pega en verify.html).
  3. Login → solo usuarios verificados pueden entrar.
  4. Perfil → requiere sesión; muestra datos y permite actualizar nombre.
  5. Reset → envía enlace para restablecer (mock: prompt).

Integración con WordPress (opcional, rápida)

  • Plantillas: convierte cada HTML en una plantilla de página (page template) y encolando styles.css y auth.js con wp_enqueue.
  • Endpoints: crea rutas con WP REST API (register_rest_route) para login/register/verify/reset/me.
  1. El correo de verificación (texto HTML que se envía al usuario).
  2. La página bienvenido-a-tu-cuenta.html con un estilo profesional y moderno.

📧 Plantilla de correo de verificación (HTML)

email-verificacion.html

html

<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <title>Verifica tu cuenta</title>
  <style>
    body { font-family: Arial, sans-serif; background:#f4f4f7; margin:0; padding:0; }
    .container { max-width:600px; margin:40px auto; background:#fff; border-radius:8px; overflow:hidden; box-shadow:0 4px 12px rgba(0,0,0,.1); }
    .header { background:#0077cc; color:#fff; padding:20px; text-align:center; }
    .content { padding:30px; color:#333; }
    .btn { display:inline-block; background:#0077cc; color:#fff; padding:12px 20px; border-radius:6px; text-decoration:none; font-weight:bold; }
    .footer { font-size:12px; color:#777; text-align:center; padding:20px; }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <h2>Verifica tu cuenta</h2>
    </div>
    <div class="content">
      <p>Hola <strong>{{nombre}}</strong>,</p>
      <p>Gracias por registrarte en nuestro sitio. Para activar tu cuenta, haz clic en el siguiente botón:</p>
      <p style="text-align:center;">
        <a href="{{verification_link}}" class="btn">Verificar mi cuenta</a>
      </p>
      <p>Si no te registraste, ignora este mensaje.</p>
    </div>
    <div class="footer">
      © 2026 ee3.es · Este correo se generó automáticamente
    </div>
  </div>
</body>
</html>

👉 Sustituye {{nombre}} y {{verification_link}} dinámicamente desde tu backend.

🌐 Página bienvenido-a-tu-cuenta.html

html

<!doctype html>
<html lang="es">
<head>
  <meta charset="utf-8">
  <title>Bienvenido a tu cuenta</title>
  <link rel="stylesheet" href="assets/styles.css">
  <style>
    body { font-family: 'Segoe UI', sans-serif; background:#f0f2f5; margin:0; }
    .card {
      max-width:600px; margin:60px auto; background:#fff;
      border-radius:12px; padding:40px; box-shadow:0 6px 20px rgba(0,0,0,.1);
    }
    h1 { color:#0077cc; margin-bottom:20px; }
    p { color:#444; line-height:1.6; }
    .btn {
      display:inline-block; background:#0077cc; color:#fff;
      padding:12px 24px; border-radius:8px; text-decoration:none; font-weight:bold;
      margin-top:20px;
    }
    .btn:hover { background:#005fa3; }
    .profile-info { margin-top:30px; }
    .profile-info p { margin:8px 0; }
  </style>
</head>
<body>
  <div class="card">
    <h1>Bienvenido a tu cuenta</h1>
    <p>Tu registro se ha completado correctamente 🎉. Ya puedes acceder a tu perfil y gestionar tu información.</p>
    
    <div class="profile-info">
      <p><strong>Nombre:</strong> {{nombre}}</p>
      <p><strong>Correo:</strong> {{email}}</p>
      <p><strong>Estado:</strong> Verificado ✅</p>
    </div>
    
    <a href="profile.html" class="btn">Ir a mi perfil</a>
  </div>
</body>
</html>

Aquí también puedes sustituir dinámicamente {{nombre}} y {{email}} desde tu backend o JavaScript.

Flujo completo

  1. Usuario se registra → recibe el correo de verificación.
  2. Hace clic en el enlace → activa su cuenta y se redirige a bienvenido-a-tu-cuenta.html.
  3. Desde ahí puede ir a su perfil o dashboard.

paso para crear la base de datos de usuarios en phpMyAdmin, pensada para el sistema de registro/verificación que hemos estado diseñando en PHP:

🛠 Pasos en phpMyAdmin

  1. Acceder a phpMyAdmin
    • Entra en tu panel de hosting y abre phpMyAdmin.
    • Selecciona Crear nueva base de datos.
    • Ponle un nombre, por ejemplo: usuarios_db.
    • Charset recomendado: utf8mb4_general_ci.
  2. Crear la tabla de usuarios
    • Dentro de la base de datos, pulsa Nueva tabla.
    • Nombre: usuarios.
    • Número de columnas: 6 (puedes ampliar según necesidades).
  3. Definir las columnas
ColumnaTipoAtributosComentario
idINT(11)AUTO_INCREMENT, PRIMARY KEYIdentificador único
nombreVARCHAR(100)NOT NULLNombre del usuario
emailVARCHAR(150)UNIQUE, NOT NULLCorreo electrónico
passwordVARCHAR(255)NOT NULLContraseña encriptada (hash)
tokenVARCHAR(64)NULLToken de verificación
verificadoTINYINT(1)DEFAULT 00 = no verificado, 1 = verificado

👉 En phpMyAdmin puedes definirlo así:

sql

CREATE TABLE usuarios (
  id INT(11) AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(100) NOT NULL,
  email VARCHAR(150) NOT NULL UNIQUE,
  password VARCHAR(255) NOT NULL,
  token VARCHAR(64),
  verificado TINYINT(1) DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Cómo se usa esta estructura

  • Registro (register.php)
    • Inserta nombre, email, contraseña (encriptada con password_hash()), token aleatorio y verificado=0.
  • Correo de verificación
    • Envía al usuario un enlace con verify.php?token=XYZ.
  • Verificación (verify.php)
    • Busca el token en la tabla.
    • Si existe, actualiza verificado=1.
  • Login (login.php)
    • Comprueba email y contraseña con password_verify().
    • Solo permite acceso si verificado=1.

Resultado

Con esta base de datos en phpMyAdmin ya tienes el núcleo para:

  • Guardar usuarios.
  • Enviar correos de verificación.
  • Confirmar cuentas.
  • Permitir login seguro.

Acceso y creación de la tabla en phpMyAdmin sin líos

Aquí tienes el camino claro, paso a paso, para entrar en phpMyAdmin y crear tu tabla sin complicarte.

Acceder a phpMyAdmin desde tu hosting

  1. Entrar al panel del hosting:
    • Accede al panel (cPanel, Plesk, o el que use tu proveedor).
  2. Abrir phpMyAdmin:
    • Busca “Bases de datos” y luego “phpMyAdmin”.
    • Haz clic para abrirlo en una nueva pestaña.

Crear (o seleccionar) la base de datos

  1. Si ya tienes base de datos creada:
    • Selecciona tu base de datos en la columna izquierda (por ejemplo, usuarios_db).
  2. Si necesitas crear una nueva:
    • Clic en “Nueva” arriba.
    • Nombre: usuarios_db (o el que prefieras).
    • Cotejamiento: utf8mb4_general_ci.
    • Crear y luego selecciona la base recién creada en la izquierda.

Opción A: Crear la tabla con el asistente

  1. Ir a “Estructura” de tu base seleccionada.
  2. Clic en “Nueva tabla”.
  3. Nombre de la tabla: usuarios.
  4. Número de columnas: 6.
  5. Definir columnas:
    • id: INT(11), A_I (Auto Increment), PRIMARY KEY.
    • nombre: VARCHAR(100), NOT NULL.
    • email: VARCHAR(150), NOT NULL, UNIQUE.
    • password: VARCHAR(255), NOT NULL.
    • token: VARCHAR(64), NULL.
    • verificado: TINYINT(1), DEFAULT 0.
  6. Guardar.

Opción B: Crear la tabla pegando SQL

  1. Ir a la pestaña “SQL” de tu base seleccionada.
  2. Pegar y ejecutar este SQL:

sql

CREATE TABLE usuarios (
  id INT(11) AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(100) NOT NULL,
  email VARCHAR(150) NOT NULL UNIQUE,
  password VARCHAR(255) NOT NULL,
  token VARCHAR(64),
  verificado TINYINT(1) DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Verificar y apuntar credenciales

  • Verificar la tabla: en la columna izquierda debe aparecer usuarios; entra y verás sus columnas.
  • Apunta tus credenciales (para PDO):
    • Servidor: normalmente localhost.
    • Base de datos: el nombre que creaste (ej. usuarios_db).
    • Usuario y contraseña: los de MySQL en tu hosting.
  • Conexión PDO (referencia):

php

$pdo = new PDO('mysql:host=localhost;dbname=usuarios_db;charset=utf8mb4', 'usuario_mysql', 'tu_password', [
  PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);

Consejos rápidos para no liarla

  • Usa siempre utf8mb4 para evitar problemas con acentos y emojis.
  • password debe ir con hash: guarda con password_hash($plain, PASSWORD_DEFAULT).
  • No dupliques emails: el índice UNIQUE en email ya te protege.
  • Si falla la creación: revisa que estás dentro de la base correcta antes de ejecutar el SQL.

ejemplos visuales creados que imitan la interfaz gráfica de phpMyAdmin, para que veas claramente dónde se crean la base de datos y la tabla.

🖼️ Ejemplo visual 1: Crear una base de datos en phpMyAdmin

  • En el menú superior verás la opción “Bases de datos”.
  • Ahí aparece un campo para escribir el nombre de la nueva base de datos y elegir el cotejamiento (utf8mb4_general_ci).
  • Luego pulsas “Crear”.

🖼️ Ejemplo visual 2: Crear una tabla dentro de la base de datos

  • Una vez seleccionada tu base en la columna izquierda, entras en la pestaña “Estructura”.
  • Verás un formulario que dice “Crear tabla”.
  • Ahí introduces el nombre de la tabla (ej. usuarios) y el número de columnas (ej. 6).
  • Después defines cada columna: idnombreemailpasswordtokenverificado.

EJEMPLOS VISUALES

como CREAR una TABLA en MYSQL PHPMYADMIN

Ingresar registros a tablas de la base de datos utilizando la interfaz gráfica de PhpMyAdmin

Creación de la base de datos y tabla

Crear tablas en MySQL

Aquí tienes un mapa visual del flujo de archivos y carpetas para tu sistema de registro con verificación por correo en PHP. Así lo tendrás todo ordenado y claro:

📂 Estructura recomendada del proyecto

Código

/mi-proyecto/
│
├── /templates/
│   └── email-verificacion.html     # Plantilla HTML del correo de verificación
│
├── /public/
│   ├── bienvenido-a-tu-cuenta.html # Página de bienvenida tras verificar
│   ├── login.html                  # Formulario de login
│   ├── register.html               # Formulario de registro
│   └── verify.php                  # Página que procesa el token de verificación
│
├── /src/
│   ├── register.php                # Script PHP que guarda usuario y envía correo
│   ├── login.php                   # Script PHP que valida credenciales
│   ├── reset.php                   # Script PHP para recuperación de contraseña
│   └── db.php                      # Conexión PDO a la base de datos
│
└── /sql/
    └── usuarios.sql                # Script SQL para crear la tabla en phpMyAdmin

🔑 Flujo de funcionamiento

  1. Usuario se registra en register.html → el formulario envía datos a register.php.
  2. register.php guarda el usuario en la tabla usuarios y carga la plantilla email-verificacion.html para enviar el correo.
  3. El correo contiene un enlace a verify.php?token=XYZ.
  4. verify.php valida el token en la base de datos y, si es correcto, redirige a bienvenido-a-tu-cuenta.html.
  5. Desde ahí, el usuario puede ir a su perfil o iniciar sesión en login.html.

🚀 Ventaja de esta estructura

  • Separación clara: plantillas, scripts PHP, páginas públicas y SQL cada uno en su sitio.
  • Modularidad: puedes cambiar el diseño del correo sin tocar el PHP.
  • Escalabilidad: fácil añadir más funciones (roles, panel admin, etc.).

Aquí tienes el script SQL completo que puedes importar directamente en phpMyAdmin para crear la tabla usuariosdentro de tu base de datos.

📜 Script usuarios.sql

sql

-- Crear la base de datos (si aún no existe)
CREATE DATABASE IF NOT EXISTS usuarios_db
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_general_ci;

-- Usar la base de datos
USE usuarios_db;

-- Crear la tabla de usuarios
CREATE TABLE IF NOT EXISTS usuarios (
  id INT(11) AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(100) NOT NULL,
  email VARCHAR(150) NOT NULL UNIQUE,
  password VARCHAR(255) NOT NULL,
  token VARCHAR(64),
  verificado TINYINT(1) DEFAULT 0,
  creado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

🛠 Cómo importarlo en phpMyAdmin

  1. Entra en phpMyAdmin desde tu hosting.
  2. Si no tienes base de datos, crea una nueva llamada usuarios_db.
  3. Selecciona la base en la columna izquierda.
  4. Ve a la pestaña SQL.
  5. Copia y pega el script anterior.
  6. Pulsa Ejecutar.

👉 Verás que se crea la tabla usuarios con las columnas necesarias para tu sistema de registro y verificación.

Campos importantes

  • id → identificador único.
  • nombre → nombre del usuario.
  • email → correo electrónico (único).
  • password → contraseña encriptada con password_hash().
  • token → clave de verificación enviada por correo.
  • verificado → estado de la cuenta (0 = no verificada, 1 = verificada).
  • creado_en → fecha y hora de registro.

Así ya tienes tu base de datos lista para conectar con tus scripts PHP (register.phpverify.phplogin.php). 🚀

Pasos para ejecutar un script SQL en phpMyAdmin

  1. Accede a phpMyAdmin
    • Desde tu panel de hosting (cPanel, Plesk, etc.), abre phpMyAdmin.
    • Verás en la parte izquierda la lista de bases de datos.
  2. Selecciona la base de datos
    • Si ya creaste la base (ej. usuarios_db), haz clic sobre ella en la columna izquierda.
    • Si no existe, primero crea una nueva desde la pestaña “Bases de datos”.
  3. Ir a la pestaña “SQL”
    • Una vez dentro de la base, en la parte superior verás varias pestañas: Estructura, SQL, Buscar, Exportar…
    • Haz clic en “SQL”.
  4. Pegar el script
    • Se abrirá un editor de texto.
    • Copia y pega el script SQL que te pasé (por ejemplo, el de creación de la tabla usuarios).
    Ejemplo:sqlCREATE TABLE usuarios ( id INT(11) AUTO_INCREMENT PRIMARY KEY, nombre VARCHAR(100) NOT NULL, email VARCHAR(150) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, token VARCHAR(64), verificado TINYINT(1) DEFAULT 0, creado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  5. Ejecutar
    • Pulsa el botón “Continuar” o “Ejecutar” (depende de la versión).
    • phpMyAdmin procesará el script y te mostrará un mensaje de éxito si todo salió bien.
  6. Verificar la tabla
    • En la columna izquierda, dentro de tu base, debe aparecer la tabla usuarios.
    • Haz clic en ella y verás las columnas que definiste.

🚀 Resultado

Con esto ya tienes tu tabla creada y lista para usar desde PHP.

  • register.php insertará registros en ella.
  • verify.php buscará el token y actualizará el campo verificado.
  • login.php comprobará email y contraseña.
Comandos básicos de MariaDB en Debian

Comandos básicos de MariaDB en Debian

LAS CONEXIONES SIMULTÁNEAS PUEDE CAUSAR UNA CAÍDA EN MariaDB, y perder la conexión del sitio web de WordPress con la Base de Datos, causando un ERROR DE CONEXIÓN CON LA BASE DE DATOS.

Arrancar, detener y reiniciar

Arrancar MariaDB sudo systemctl start mariadb

Detener MariaDB sudo systemctl stop mariadb

Reiniciar MariaDB sudo systemctl restart mariadb

Estado del servicio

  • Ver estado (sin quedarse dentro del visor)bashsudo systemctl status mariadb --no-pager
  • Ver si arranca al inicio del sistemabashsudo systemctl is-enabled mariadb

Logs y errores

  • Ver últimos registros de MariaDBbashjournalctl -u mariadb -n 50 --no-pager
  • Ver logs en tiempo realbashjournalctl -u mariadb -f

Comprobación de conexión

  • Entrar al cliente MySQL/MariaDBbashmysql -u root -p
  • Probar conexión remotabashmysql -u usuario -p -h IP_DEL_VPS

Consejo: Si alguna vez te quedas “atrapado” viendo el estado con systemctl status, recuerda que basta con pulsar q para salir y volver al prompt.

Aquí tienes una mini‑guía de optimización de MariaDB para un VPS con 2 GB de RAM. Con estos ajustes tu servidor debería mantenerse estable y evitar que el sistema lo mate por falta de memoria.

⚙️ Configuración recomendada en /etc/mysql/mariadb.conf.d/50-server.cnf

Dentro del bloque [mysqld] añade o ajusta estas líneas:

ini

[mysqld]
# Memoria principal para InnoDB (ajustada a 256 MB para 2 GB de RAM)
innodb_buffer_pool_size = 256M

# Número máximo de conexiones simultáneas
max_connections = 100

# Tamaño máximo de tablas temporales en memoria
tmp_table_size = 64M
max_heap_table_size = 64M

# Caché de consultas (puede ayudar en sitios con muchas lecturas repetidas)
query_cache_size = 32M
query_cache_type = 1

# Limitar el tamaño del log binario si no usas replicación
expire_logs_days = 7
max_binlog_size = 100M

# Evitar que MariaDB consuma demasiada RAM en operaciones grandes
join_buffer_size = 2M
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 4M

Pasos para aplicar

Edita el archivo: sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

Añade el bloque [mysqld] con los parámetros anteriores.

Guarda con Ctrl+O, confirma con Enter y sal con Ctrl+X.

Reinicia MariaDB: sudo systemctl restart mariadb sudo systemctl status mariadb --no-pager

Consejos adicionales

  • Activa swap si tu VPS no la tiene, para evitar OOM‑kill:bashsudo fallocate -l 1G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile
  • Monitoriza consumo con:bashhtop
  • Ajusta valores si notas que MariaDB sigue consumiendo demasiada RAM.

script automático pensado para tu VPS Debian con 2 GB de RAM. Este script ajusta los parámetros de MariaDB y activa un archivo de swap de 1 GB para evitar que el sistema vuelva a matar el proceso por falta de memoria.

Aquí tienes un script avanzado que no solo optimiza MariaDB y activa swap, sino que además monitoriza el servicioy lo reinicia automáticamente si detecta un fallo por OOM‑kill (falta de memoria).

Script avanzado: Optimización + Monitorización MariaDB

Guárdalo como mariadb_monitor.sh:

bash

#!/bin/bash
# Script avanzado para optimizar y monitorizar MariaDB en VPS Debian (2 GB RAM)

CONF="/etc/mysql/mariadb.conf.d/50-server.cnf"

echo "🔧 Ajustando configuración de MariaDB..."

# Añadir bloque [mysqld] si no existe
if ! grep -q "

\[mysqld\]

" $CONF; then
    echo "[mysqld]" | sudo tee -a $CONF
fi

# Añadir parámetros optimizados
sudo tee -a $CONF > /dev/null <<EOL
innodb_buffer_pool_size = 256M
max_connections = 100
tmp_table_size = 64M
max_heap_table_size = 64M
query_cache_size = 32M
query_cache_type = 1
join_buffer_size = 2M
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 4M
EOL

echo "✅ Configuración añadida a $CONF"

# Reiniciar MariaDB
sudo systemctl restart mariadb
echo "✅ MariaDB reiniciado"

# Crear swap de 1 GB si no existe
if ! grep -q "/swapfile" /etc/fstab; then
    echo "🔧 Creando archivo de swap de 1 GB..."
    sudo fallocate -l 1G /swapfile
    sudo chmod 600 /swapfile
    sudo mkswap /swapfile
    sudo swapon /swapfile
    echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab
    echo "✅ Swap activado y configurado en /etc/fstab"
else
    echo "ℹ️ Swap ya está configurado en el sistema"
fi

# Monitorización: comprobar si MariaDB está activo
echo "🔍 Comprobando estado de MariaDB..."
if ! systemctl is-active --quiet mariadb; then
    echo "⚠️ MariaDB no está activo. Intentando reinicio..."
    sudo systemctl restart mariadb
    if systemctl is-active --quiet mariadb; then
        echo "✅ MariaDB reiniciado correctamente tras fallo."
    else
        echo "❌ Error: MariaDB no pudo reiniciarse. Revisa logs con: journalctl -u mariadb -xe"
    fi
else
    echo "✅ MariaDB está activo y funcionando."
fi

echo "🎉 Script completado. MariaDB optimizado y monitorizado."

Cómo usarlo

Crea el archivo: nano mariadb_monitor.sh

Pega el contenido.

Guarda con Ctrl+O, confirma con Enter, y sal con Ctrl+X.

Dale permisos de ejecución: chmod +x mariadb_monitor.sh

Ejecútalo:./mariadb_monitor.sh

Soluciones prácticas

1. Ajustar max_connections

  • Con 2 GB de RAM puedes subirlo a 100 (como ya configuramos).
  • No conviene subirlo demasiado, porque cada conexión consume memoria.

2. Usar un pool de conexiones

  • Instala y configura un pool de conexiones (ej. ProxySQL o MariaDB MaxScale).
  • Esto permite que las aplicaciones web reutilicen conexiones en lugar de abrir nuevas cada vez.

3. Optimizar consultas

  • Revisa que las consultas SQL sean rápidas y usen índices.
  • Evita consultas pesadas que bloqueen la base de datos.

4. Cachear resultados

  • Usa memcached o Redis para cachear datos frecuentes y reducir la carga sobre MariaDB.

5. Escalar infraestructura

  • Si el tráfico sigue creciendo, considera:
    • Migrar a un VPS con más RAM.
    • Usar un balanceador de carga con varias instancias de base de datos.

Web Recomendada

Comandos SSH

📘 Módulo 19: CSS Avanzado – Animaciones con SVG y Canvas

📘 Módulo 19: CSS Avanzado – Animaciones con SVG y Canvas

Aprender a integrar SVG en animaciones CSS. Introducir animaciones con Canvas controladas por CSS y JavaScript.

Objetivos

  • Aprender a integrar SVG en animaciones CSS.
  • Usar propiedades como stroke-dasharray y stroke-dashoffset para animar trazos.
  • Introducir animaciones con Canvas controladas por CSS y JavaScript.
  • Crear efectos visuales complejos y dinámicos para iconos, gráficos y fondos.

🔹 1. Animaciones con SVG (líneas y trazos)

css

svg path {
  stroke: #003366;
  stroke-width: 3;
  fill: none;
  stroke-dasharray: 300;   /* longitud del trazo */
  stroke-dashoffset: 300;  /* oculto inicialmente */
  animation: dibujar 3s linear forwards;
}

@keyframes dibujar {
  to { stroke-dashoffset: 0; }
}

👉 El trazo de un icono se dibuja progresivamente.

🔹 2. Animaciones de relleno en SVG

css

svg circle {
  fill: transparent;
  stroke: #ff6600;
  stroke-width: 4;
  transition: fill 0.5s ease;
}

svg circle:hover {
  fill: #ff6600;
}

👉 El círculo se rellena al pasar el ratón.

🔹 3. Canvas con CSS y JS

Canvas requiere JavaScript, pero se puede combinar con CSS para efectos visuales.

html

<canvas id="animacion" width="400" height="400"></canvas>

js

const ctx = document.getElementById("animacion").getContext("2d");
let x = 0;
function animar() {
  ctx.clearRect(0, 0, 400, 400);
  ctx.fillStyle = "#003366";
  ctx.beginPath();
  ctx.arc(x, 200, 20, 0, Math.PI * 2);
  ctx.fill();
  x += 2;
  requestAnimationFrame(animar);
}
animar();

👉 Una bola se mueve suavemente dentro del canvas.

🔹 4. Combinación SVG + CSS

  • Iconos que se dibujan solos al cargar la página.
  • Gráficos con líneas animadas que muestran datos progresivamente.
  • Botones con iconos SVG interactivos que cambian color y forma.

📝 Actividad práctica

  1. Crea un icono SVG cuyo trazo se dibuje progresivamente con stroke-dasharray.
  2. Implementa un círculo SVG que se rellene al hover.
  3. Diseña una animación en Canvas con una bola que rebote dentro del área.

MÓDULO 20 CSS Integración multimedia

BOTON HTML CON ICONO Y ENLACE
Publicidad