W3docs

Encuesta AJAX con PHP

Aprende a construir una encuesta AJAX en PHP que registra votos y muestra resultados en vivo sin recargar la página, usando fetch, JSON y MySQL.

¿Qué Es una Encuesta AJAX?

Una encuesta AJAX es un pequeño widget de votación que permite al usuario elegir una opción, envía ese voto al servidor en segundo plano y luego muestra los resultados actualizados, todo sin recargar la página. AJAX (Asynchronous JavaScript and XML) es la técnica de intercambiar datos con el servidor usando JavaScript después de que la página ya se ha cargado.

Este capítulo construye una encuesta completa: una tabla MySQL para almacenar las opciones y sus conteos de votos, un script PHP que registra un voto y devuelve el recuento actual como JSON, y una pequeña cantidad de JavaScript que envía el voto y muestra los resultados.

Si quieres actualizar continuamente datos con un temporizador (un marcador en vivo, un panel de estado), los mismos componentes básicos aplican — ese patrón se llama polling, y lo vemos al final del capítulo.

¿Por Qué Usar AJAX para una Encuesta?

  • Sin recarga de página. El usuario permanece en la página; solo cambia el área de la encuesta. Esto se siente instantáneo y mantiene el resto de la página (posición de desplazamiento, video, entrada de formulario) intacto.
  • Menos datos transferidos. En lugar de reenviar todo el documento HTML, el servidor devuelve solo los conteos de votos como un pequeño payload JSON.
  • Resultados en vivo. Dado que la respuesta son datos, no marcado, puedes renderizar una barra de resultados de inmediato e incluso actualizarla con un temporizador para reflejar los votos de otros usuarios.

Paso 1 — Crear la Tabla de Base de Datos

Cada opción de la encuesta es una fila. Almacenamos el texto de la opción y un contador de votos acumulado.

CREATE TABLE poll_options (
    id INT AUTO_INCREMENT PRIMARY KEY,
    option_text VARCHAR(100) NOT NULL,
    votes INT NOT NULL DEFAULT 0
);

INSERT INTO poll_options (option_text) VALUES
    ('PHP'),
    ('JavaScript'),
    ('Python');

Si eres nuevo en la creación de tablas, consulta Crear una tabla MySQL e Insertar datos.

Paso 2 — Construir el Formulario HTML

El formulario lista las opciones como botones de radio y reserva un contenedor para los resultados.

<form id="pollForm">
  <p>What is your favorite language?</p>
  <label><input type="radio" name="option" value="1"> PHP</label>
  <label><input type="radio" name="option" value="2"> JavaScript</label>
  <label><input type="radio" name="option" value="3"> Python</label>
  <button type="submit">Vote</button>
</form>

<div id="pollResults"></div>

El value de cada botón de radio es el id de la opción en la base de datos — eso es lo único que necesitamos enviar al servidor.

Paso 3 — Escribir el Manejador PHP

El script PHP hace dos tareas: registrar un voto (cuando se envía uno) y devolver los resultados actuales como JSON. Siempre usa sentencias preparadas para que un valor proveniente del navegador nunca pueda interpretarse como SQL.

<?php
header('Content-Type: application/json');

$dsn = "mysql:host=localhost;dbname=your_database;charset=utf8mb4";
$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];

try {
    $pdo = new PDO($dsn, 'username', 'password', $options);

    // If a vote was submitted, increment that option's counter.
    if (isset($_POST['option'])) {
        $optionId = (int) $_POST['option'];
        $update = $pdo->prepare(
            "UPDATE poll_options SET votes = votes + 1 WHERE id = :id"
        );
        $update->execute([':id' => $optionId]);
    }

    // Always return the current tally.
    $rows = $pdo->query(
        "SELECT id, option_text, votes FROM poll_options ORDER BY id"
    )->fetchAll();

    $total = array_sum(array_column($rows, 'votes'));

    echo json_encode([
        'status'  => 'success',
        'total'   => $total,
        'options' => $rows,
    ]);
} catch (PDOException $e) {
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => 'Database error']);
}

Convertir el id entrante con (int) y vincularlo con :id significa que el valor se trata estrictamente como un número, no como parte de la consulta. Para más información, lee Sentencias Preparadas en PHP y json_encode().

Paso 4 — Enviar el Voto con JavaScript

Interceptamos el evento submit del formulario, enviamos la opción seleccionada con fetch() y luego dibujamos una barra de resultados a partir de la respuesta JSON.

const form = document.getElementById('pollForm');
const resultsBox = document.getElementById('pollResults');

form.addEventListener('submit', function (event) {
  event.preventDefault(); // Stop the normal page reload.

  const selected = form.querySelector('input[name="option"]:checked');
  if (!selected) return; // Nothing chosen yet.

  const body = new URLSearchParams({ option: selected.value });

  fetch('poll.php', { method: 'POST', body })
    .then(response => response.json())
    .then(showResults)
    .catch(error => console.error('Vote failed:', error));
});

function showResults(data) {
  if (data.status !== 'success') {
    resultsBox.textContent = 'Could not load results.';
    return;
  }

  resultsBox.innerHTML = data.options.map(opt => {
    const percent = data.total
      ? Math.round((opt.votes / data.total) * 100)
      : 0;
    return `<div>${opt.option_text}: ${opt.votes} votes (${percent}%)</div>`;
  }).join('');
}

event.preventDefault() es lo que evita que el navegador realice un envío completo, que es el punto central de AJAX. El porcentaje se calcula en el cliente a partir de los conteos que devolvió el servidor, por lo que la barra siempre coincide con los datos más recientes.

Paso 5 — Mantener los Resultados en Vivo con Polling

Hasta ahora, los resultados se actualizan solo cuando este usuario vota. Para reflejar los votos de otros usuarios, haz polling al servidor con un temporizador — solicita el recuento más reciente cada pocos segundos y vuelve a renderizar:

function refreshResults() {
  fetch('poll.php') // GET, no vote — just read the tally.
    .then(response => response.json())
    .then(showResults)
    .catch(error => console.error('Refresh failed:', error));
}

setInterval(refreshResults, 5000); // Every 5 seconds.

Dado que el manejador PHP devuelve el recuento en cada solicitud (voto o no), un simple GET es suficiente para obtener números actualizados. Elige el intervalo con cuidado: un intervalo corto se siente más en vivo pero genera más solicitudes. Para datos que deben ser verdaderamente en tiempo real, WebSockets o Server-Sent Events son una mejor opción que el polling de intervalo fijo.

Errores Comunes

  • Olvidar event.preventDefault(). Sin ello, el formulario recarga la página y la llamada AJAX se cancela a mitad de camino.
  • Confiar en el id de la opción. Siempre conviértelo/valídalo y usa una sentencia preparada; nunca concatenes $_POST en SQL.
  • Doble conteo. Este ejemplo básico permite que un navegador vote muchas veces. En producción, restringe por sesión, cookie o IP.
  • Hacer polling demasiado agresivo. Un intervalo de un segundo en una página con mucho tráfico puede sobrecargar el servidor; 3–10 segundos suele ser más que suficiente.

Resumen

Una encuesta AJAX combina una tabla MySQL, un endpoint PHP que registra un voto y devuelve el recuento como JSON, y JavaScript que envía con fetch() y muestra los resultados — sin necesidad de recargar la página. Agrega un poll con setInterval para mantener los números en vivo para todos.

graph TD;
    A(User Selects Option and Clicks Vote) --> B(JavaScript Sends POST with fetch);
    B --> C(PHP Increments Vote with Prepared Statement);
    C --> D(PHP Returns Tally as JSON);
    D --> E(JavaScript Renders Results Bar);
    F(Timer Every 5s) --> G(GET poll.php for Latest Tally);
    G --> D;

Práctica

Práctica
¿Cuáles son los pasos para crear una encuesta AJAX en PHP?
¿Cuáles son los pasos para crear una encuesta AJAX en PHP?
Was this page helpful?