Simple Polls and Voting Web App
Build a small polling website in PHP: anyone can create a poll with a question and several options, share its link, and let people vote. Each visitor can vote only once per poll, and the results page shows each option's votes as a percentage with a colored bar. Polls and votes are stored in MySQL through PDO. It's a practical beginner project: you'll learn how HTML forms and PHP work together, sessions and cookies, database tables and relationships, safe queries with PDO prepared statements, and validating what users submit.
- Estimate
- ~9.5h
- Steps
- 6
- Completed by
- 0
- Proposed by
- codeseed.app
MySQL · PDO
Project roadmap
- 01
Design the database
~1hInstall PHP 8 and MySQL (or run MySQL with Docker). Write schema.sql with three tables: polls (id, question, created_at), options (id, poll_id, text) and votes (id, poll_id, option_id, voter_key, created_at), with foreign keys and a unique index on poll_id plus voter_key so the database itself prevents double voting. Create a db.php file that returns a PDO connection with exceptions enabled. Done when: schema.sql creates the tables, and db.php connects.
- 02
Create polls
~2hBuild create.php with a form for the question and 2 to 6 option fields. On submit, check that the question has 5 to 200 characters and there are at least 2 non-empty, different options. Insert the poll and its options in one transaction with prepared statements, then redirect to the poll's page. Show errors next to the form and keep what the user typed. Done when: a valid poll is saved and opens on its own page.
- 03
Vote once per poll
~2hBuild poll.php?id=... showing the question and options as radio buttons. Give each visitor a random voter key, stored in the session and in a long-lived cookie. On submit, check that the option belongs to this poll, then insert the vote. If the unique index rejects it because this visitor already voted, show a message instead of an error. Done when: voting works once, and a second vote from the same browser is refused.
- 04
Show the results
~1.5hBuild results.php?id=... that counts votes per option with one query (LEFT JOIN plus GROUP BY, so options with 0 votes still show), and displays each option with its vote count, its percentage rounded to one decimal, and a bar whose width matches the percentage. Show the total votes. Redirect voters here after voting. Done when: the percentages add up to about 100% and match the votes.
- 05
List polls and add styling
~1.5hMake index.php list the latest polls with their vote counts, linking to each one. Escape every piece of user text with htmlspecialchars. Add a simple CSS file so the forms and result bars look good on phones and desktops. Done when: the home page lists polls, and a question containing <script> is shown as plain text.
- 06
Test the app
~1.5hWrite a test checklist in TESTING.md and go through it: creating a poll with missing or duplicate options, voting for an option from a different poll (by editing the form), voting twice, a poll with no votes, and a non-existent poll id. Fix anything that breaks. Done when: every case in TESTING.md behaves correctly and is marked as checked.
Resources
Ready to build this?
Get a GitHub repo and start building. Your AI reviewer checks each step as you go.
Tech stack