PHP AJAX Poll - Voting System
Learn how to create an interactive PHP AJAX poll that allows users to vote in real-time with live result updates. This tutorial will guide you through building a robust voting system using PHP and AJAX, making your web applications more engaging and responsive.
Introduction
Polling or voting systems are popular features on many websites, enabling users to share opinions quickly and see immediate results. Using PHP and AJAX together lets you build a dynamic poll that updates without reloading the page, providing a smooth user experience.
In this tutorial, we'll create a simple yet effective PHP AJAX poll that records votes in a MySQL database and updates the displayed results in real-time.
Prerequisites
- Basic knowledge of PHP, MySQL, and JavaScript
- A working web server with PHP 7+ and MySQL support
- Basic understanding of AJAX and how it works
- Access to phpMyAdmin or command line to create MySQL database and tables
Setup Steps
1. Create Database and Table
First, create a MySQL database and a table to store the poll options and votes.
CREATE DATABASE poll_db;
USE poll_db;
CREATE TABLE poll_options (
id INT AUTO_INCREMENT PRIMARY KEY,
option_text VARCHAR(100) NOT NULL,
votes INT DEFAULT 0
);
INSERT INTO poll_options (option_text, votes) VALUES
('Option 1', 0),
('Option 2', 0),
('Option 3', 0),
('Option 4', 0);
2. Database Connection (db.php)
Create a PHP script to connect to the MySQL database.
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "poll_db";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
?>
Building the Poll Interface
3. Poll Frontend (index.php)
We use HTML to display poll questions and options, and JavaScript to handle AJAX requests.
<?php include 'db.php'; ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>PHP AJAX Poll - Voting System</title>
<style>
body { font-family: Arial, sans-serif; max-width: 600px; margin: 50px auto; }
.poll-option { margin-bottom: 15px; }
.result-bar { background: #f4f4f4; border: 1px solid #ddd; height: 20px; position: relative; }
.fill-bar { background: #4CAF50; height: 100%; text-align: right; padding-right: 5px; color: white; }
</style>
</head>
<body>
<h2>Vote for your favorite option</h2>
<form id="pollForm">
<?php
$sql = "SELECT * FROM poll_options";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
echo '<div class="poll-option">';
echo '<input type="radio" name="pollOption" value="' . $row["id"] . '" id="option' . $row["id"] . '">';
echo '<label for="option' . $row["id"] . '">' . htmlspecialchars($row["option_text"]) . '</label>';
echo '</div>';
}
}
?>
<button type="button" onclick="submitVote()">Vote</button>
</form>
<h3>Poll Results</h3>
<div id="pollResults"></div>
<script>
// Load current results on page load
document.addEventListener('DOMContentLoaded', fetchResults);
function submitVote() {
let form = document.getElementById('pollForm');
let selected = form.pollOption.value;
if (!selected) {
alert('Please choose an option before voting.');
return;
}
let xhr = new XMLHttpRequest();
xhr.open('POST', 'vote.php', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
fetchResults();
}
};
xhr.send('option_id=' + selected);
}
function fetchResults() {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'results.php', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
document.getElementById('pollResults').innerHTML = xhr.responseText;
}
};
xhr.send();
}
</script>
</body>
</html>
Backend Processing with AJAX
4. Updating Votes (vote.php)
This script receives the AJAX POST request and updates the vote count in the database.
<?php
include 'db.php';
if (isset($_POST['option_id'])) {
$option_id = intval($_POST['option_id']);
$sql = "UPDATE poll_options SET votes = votes + 1 WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $option_id);
if ($stmt->execute()) {
echo "Vote counted";
} else {
echo "Failed to record vote";
}
$stmt->close();
} else {
echo "Invalid request";
}
$conn->close();
?>
5. Fetching Results (results.php)
This script fetches and returns the poll results dynamically in HTML format.
<?php
include 'db.php';
$sql = "SELECT SUM(votes) AS total_votes FROM poll_options";
$result = $conn->query($sql);
$total_votes = 0;
if ($result && $row = $result->fetch_assoc()) {
$total_votes = $row['total_votes'];
}
$sql = "SELECT * FROM poll_options";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
$percentage = $total_votes > 0 ? round(($row['votes'] / $total_votes) * 100) : 0;
echo '<div>' . htmlspecialchars($row['option_text']) . ': ' . $row['votes'] . ' votes</div>';
echo '<div class="result-bar">';
echo '<div class="fill-bar" style="width:' . $percentage . '%;">' . $percentage . '%</div>';
echo '</div><br>';
}
} else {
echo "No poll options found.";
}
$conn->close();
?>
Explanation of the Code
- index.php: Displays poll options and has AJAX code to send votes and fetch live results.
- vote.php: Accepts POST requests and increments the vote count for the selected option securely using prepared statements.
- results.php: Retrieves the aggregated vote counts and calculates percentage shares to build visual bars.
- AJAX triggers two actions: submitting votes and retrieving updated results without page refresh.
Best Practices
- Always use
prepared statementsto prevent SQL injection. - Validate and sanitize user inputs on the server side.
- Use proper error handling and user-friendly messages.
- Restrict multiple votes per userβe.g., by tracking IP addresses or using cookies (not covered here for simplicity).
- Make the UI accessible and responsive for better user experience.
- Keep JavaScript unobtrusive and separate from HTML when scaling the project.
Common Mistakes to Avoid
- Not validating the
option_idreceived from AJAX requests. - Failing to handle database connection errors gracefully.
- Updating the vote count incorrectly or allowing multiple increments unintentionally.
- Not updating the results display after voting, losing real-time interactivity.
- Mishandling AJAX callbacks causing UI to freeze or behave unexpectedly.
Interview Questions
Junior Level
- Q1: What role does AJAX play in the PHP AJAX poll system?
A: AJAX updates voting results and submits votes without reloading the page, making the poll interactive. - Q2: How do you prevent SQL injection when updating votes?
A: By using prepared statements with bound parameters in PHP. - Q3: What HTTP method is used to submit votes in this system?
A: POST method is used to securely send the selected option ID. - Q4: Why do we need to fetch results separately after voting?
A: To update the vote counts and percentages in real-time for the user. - Q5: What happens if a user tries to vote without selecting an option?
A: The system alerts the user to choose an option before voting.
Mid Level
- Q1: How are vote counts stored and incremented in the database?
A: Votes are stored as an integer field and incremented using an UPDATE query likevotes = votes + 1. - Q2: Describe the process that occurs after clicking the vote button.
A: JavaScript sends the selected option ID via AJAX POST tovote.php, which updates the database, then the results are fetched again via AJAX GET. - Q3: How are percentages for the result bars calculated?
A: Percentage = (votes for an option / total votes) * 100, rounded to display progress bars. - Q4: How can you enhance this system to prevent multiple votes from one user?
A: Use cookies, sessions, IP tracking, or user authentication to restrict voting frequency. - Q5: What are the security considerations while implementing the AJAX poll?
A: Validate inputs, prevent SQL injection, sanitize outputs to prevent XSS, and avoid exposing sensitive info.
Senior Level
- Q1: How would you scale this PHP AJAX poll for high traffic environments?
A: Use caching for frequent result queries, implement vote queuing, optimize queries, and consider using NoSQL or Redis for fast increments. - Q2: Discuss how you would secure the system against vote manipulation.
A: Implement rate limiting, CAPTCHA validation, user authentication, IP throttling, and audit logs to detect suspicious voting patterns. - Q3: How can this poll be refactored to use modern PHP frameworks?
A: Use Laravel or Symfony to manage routing, validation, database ORM, and AJAX APIs nicely separated from the frontend. - Q4: Describe how you would implement real-time updates using WebSockets instead of AJAX.
A: Integrate WebSocket server (e.g., Ratchet in PHP) to push live vote updates to clients without polling via AJAX. - Q5: How would you internationalize the poll system for multi-language support?
A: Store poll questions/options in language-specific tables or use translation files, detect user language, and display accordingly.
FAQ
Q1: Can I allow multiple votes per user?
Yes, but typically voting systems limit votes per user. You can implement this by tracking users via sessions, cookies, or IPs.
Q2: How do I style the poll bars differently?
Modify the CSS classes .result-bar and .fill-bar in the index.php or external stylesheet.
Q3: What if my AJAX request fails?
Always implement error handling in JavaScript to inform users if requests fail (e.g., network issues) and possibly retry or log errors.
Q4: Can this poll work without JavaScript?
Without JavaScript and AJAX, the page must reload for every vote, losing real-time interactivity. The system will work but with degraded UX.
Q5: How can I export poll results?
You can create an admin PHP page that queries the database and outputs results in CSV, JSON, or PDF formats for download.
Conclusion
Building a PHP AJAX poll enables you to create engaging voting features with live result updates. This tutorial covered setting up the database, creating secure backend PHP scripts, and integrating AJAX on the frontend to fetch and submit data asynchronously.
By following best practices and avoiding the common pitfalls shared here, you can extend this foundation to develop advanced, secure, and responsive polling systems tailored to your needs.
Start implementing your own interactive voting system today and delight your users with a seamless polling experience!