In this tutorial, we'll develop a secure poll and voting system using PHP and MySQL. This system will allow you to interact with your audience and display a collection of polls. You'll learn to create polls, implement a voting system, delete polls, and display the list of published polls.
A poll and voting system lets people share their opinions on a question by choosing from several answer options. Users select their choice, and the system counts all the votes to show the overall results. This is often used in surveys, market research, and online platforms to gather feedback and understand what people think about various topics.
During poll creation, you can specify multiple answers, as they will be stored in a separate database table. One table will store poll-related data (title, description, etc.), while the other will store the answers, linking both to display the poll list.
The Advanced package includes additional features and a download link to the source code.
Contents Getting Started What You Will Learn in this Tutorial Requirements File Structure and Setup Creating the Database and setting-up Tables Creating the Stylesheet (CSS3) Creating the Poll and Voting System with PHP Functions Index Page Create Page Vote Page Result Page Delete Page 1. Getting StartedBefore we jump into programming our poll and voting system, there are a few requirements that need to be met. We need to install the development tools and set up the file structure for our app.
1.1. What You Will Learn in this Tutorial Form Design — Design a Poll and Voting app with HTML5 and CSS3. Poll System — Create a working poll system with PHP & MySQL (create polls, delete polls, and view polls). Voting System — Each poll will consist of answers that the user can select to cast a vote and subsequently view the result. MySQL Database Interaction — Interact with a MySQL database using the PHP PDO interface. All data entered during the creation phase will be stored in the MySQL database. Basic Template System — We'll create a basic template system for our app, which will consist of header and footer functions. Those functions can then be implemented on all the pages we create. It's so we don't he to write the same code over and over. 1.2. Requirements Download and install XAMPP — XAMPP is a web server that includes the essential software for web developers (PHP, MySQL, Apache, etc). Skip this step if you already he a development server installed. 1.3. File Structure & SetupNigate to your XAMPP htdocs directory (usually located at C:\xampp\htdocs) and create the following files and directories:
File Structure\-- phppoll |-- functions.php |-- index.php |-- create.php |-- vote.php |-- result.php |-- delete.php |-- style.css
Each file will contain the following:
functions.php — The functions file will contain the template and database connection functions. index.php — The index page will contain the list of published polls and the nigation buttons. create.php — The create page will contain form input fields, which we can use to create new polls. vote.php — The vote page will consist of poll answers with the option to cast a vote. result.php — The result page will show the results for the specified poll, while each answer will show the number of votes and the percentage bar. style.css — The stylesheet (CSS3) for our poll and voting system. 2. Creating the Database and setting-up TablesIf you he installed XAMPP, you can create the MySQL database with phpMyAdmin. Although, you need to make sure you start your web server: open the XAMPP control panel and click the Start button for both Apache and MySQL.
Nigate to http://localhost/phpmyadmin/ in your browser. Click the SQL tab at the top and execute the following SQL statement: CREATE DATABASE IF NOT EXISTS `phppoll` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; USE `phppoll`; CREATE TABLE IF NOT EXISTS `polls` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` text NOT NULL, `description` text NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; INSERT INTO `polls` (`id`, `title`, `description`) VALUES (1, 'What''s your forite programming language?', ''); CREATE TABLE IF NOT EXISTS `poll_answers` ( `id` int(11) NOT NULL AUTO_INCREMENT, `poll_id` int(11) NOT NULL, `title` text NOT NULL, `votes` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; INSERT INTO `poll_answers` (`id`, `poll_id`, `title`, `votes`) VALUES (1, 1, 'PHP', 0), (2, 1, 'Python', 0), (3, 1, 'C#', 0), (4, 1, 'Ja', 0);In phpMyAdmin, our database should resemble the following:
A summary of each table and the columns associated with them:
polls table — This table will contain information related to the polls we create (title and description). id — The unique ID for the poll, which will be auto-incremented, meaning the number will increase as more rows are created. title — The title of the poll, which could be a question, etc. description — The description of the poll, which is optional during the creation phase. poll_answers table — This table will contain all the answers for our created polls. id — Unique ID, which will be auto incremented. poll_id — The poll ID, which will be associated with the id column in the polls table. It's how we can relate both tables. title — The title of the poll answer. votes — The number of votes the answer has.To make sure the database has been successfully imported, you can check on phpMyAdmin — click the database name in the left side nigation panel and you should see the following:
3. Creating the Stylesheet (CSS3)
The stylesheet will format the structure of our poll and voting system and make it look more appealing. Add the following CSS code to the style.css file:
* { box-sizing: border-box; font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-size: 16px; } body { background-color: #FFFFFF; margin: 0; } .ntop { background-color: #313d4e; height: 60px; width: 100%; border: 0; } .ntop div { display: flex; margin: 0 auto; width: 900px; height: 100%; } .ntop div h1, .ntop div a { display: inline-flex; align-items: center; } .ntop div h1 { flex: 1; font-size: 20px; padding: 0; margin: 0; color: #eaeced; font-weight: normal; } .ntop div a { padding: 0 20px; text-decoration: none; color: #c1c5ca; font-weight: 500; } .ntop div a svg { fill: #c1c5ca; margin: 2px 5px 0 0; } .ntop div a:hover { color: #eaeced; } .content { width: 900px; margin: 0 auto; } .content h2 { margin: 0; padding: 25px 0 10px 0; font-size: 22px; font-weight: 600; color: #474b50; } .home .create-poll { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; appearance: none; cursor: pointer; border: 0; background: #2873cf; color: #FFFFFF; padding: 0 14px; font-size: 14px; font-weight: 600; border-radius: 4px; height: 35px; margin-top: 10px; box-shadow: 0px 0px 6px 1px rgba(45, 54, 68, 0.1); } .home .create-poll:hover { background: #266cc2; } .home table { width: 100%; margin-top: 30px; border-collapse: collapse; } .home table thead { border-bottom: 1px solid #ebedf0; } .home table thead td { padding: 15px; font-weight: 500; color: #787a7c; font-size: 14px; } .home table tbody tr { border-bottom: 1px solid #ebedf0; } .home table tbody tr:nth-child(odd) { background-color: #fafafc; } .home table tbody tr td { padding: 15px; } .home table tbody tr td:nth-child(1) { color: #a8aaad; } .home table tbody tr td .poll-answer { display: inline-flex; align-items: center; justify-content: center; padding: 4px 10px; background-color: #f8eabd; color: #c99f15; border-radius: 15px; margin-right: 4px; font-size: 12px; font-weight: 500; } .home table tbody tr td.actions { padding: 8px; text-align: right; } .home table tbody tr td.actions .view, .home table tbody tr td.actions .trash { display: inline-flex; text-align: right; text-decoration: none; color: #FFFFFF; padding: 7px 9px; border-radius: 5px; margin-left: 3px; } .home table tbody tr td.actions .view svg, .home table tbody tr td.actions .trash svg { fill: #fff; } .home table tbody tr td.actions .trash { background-color: #b73737; } .home table tbody tr td.actions .trash:hover { background-color: #a33131; } .home table tbody tr td.actions .view { background-color: #37b770; } .home table tbody tr td.actions .view:hover { background-color: #31a364; } .update form { padding: 15px 0; display: flex; flex-flow: column; width: 400px; } .update form label { display: inline-flex; width: 100%; padding: 10px 0; margin-right: 25px; font-weight: 500; font-size: 14px; color: #474b50; } .update form input, .update form textarea { padding: 10px; width: 100%; margin-right: 25px; margin-bottom: 15px; border: 1px solid #dcdee0; border-radius: 5px; } .update form input::placeholder, .update form textarea::placeholder { color: #999a9e; } .update form textarea { height: 200px; } .update form button { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; appearance: none; cursor: pointer; border: 0; background: #2873cf; color: #FFFFFF; padding: 0 14px; font-size: 14px; font-weight: 600; border-radius: 4px; height: 35px; width: 120px; margin-top: 10px; box-shadow: 0px 0px 6px 1px rgba(45, 54, 68, 0.1); } .update form button:hover { background: #266cc2; } .delete .yesno { display: flex; } .delete .yesno a { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; appearance: none; cursor: pointer; border: 0; background: #2873cf; color: #FFFFFF; padding: 0 14px; font-size: 14px; font-weight: 600; border-radius: 4px; height: 35px; width: 70px; margin: 10px 10px 10px 0; box-shadow: 0px 0px 6px 1px rgba(45, 54, 68, 0.1); } .delete .yesno a:hover { background: #266cc2; } .poll-vote form { display: flex; flex-flow: column; } .poll-vote form label { padding-bottom: 12px; } .poll-vote form input[type=radio] { transform: scale(1.1); margin-right: 10px; } .poll-vote form button, .poll-vote form a { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; appearance: none; cursor: pointer; border: 0; background: #2873cf; color: #FFFFFF; padding: 0 14px; font-size: 14px; font-weight: 600; border-radius: 4px; height: 35px; width: 120px; margin-top: 10px; box-shadow: 0px 0px 6px 1px rgba(45, 54, 68, 0.1); } .poll-vote form button:hover, .poll-vote form a:hover { background: #266cc2; } .poll-vote form a { text-align: center; text-decoration: none; background-color: #37afb7; margin-left: 6px; } .poll-vote form a:hover { background-color: #319ca3; } .poll-result .wrapper { display: flex; flex-flow: column; } .poll-result .wrapper .poll-question { width: 50%; padding-bottom: 7px; } .poll-result .wrapper .poll-question p { margin: 0; padding: 7px 0; } .poll-result .wrapper .poll-question p span { font-size: 14px; color: #88898d; } .poll-result .wrapper .poll-question .result-bar-wrapper { background-color: #f0f3f1; border-radius: 15px; overflow: hidden; max-width: 340px; } .poll-result .wrapper .poll-question .result-bar-wrapper .result-bar { display: flex; height: 25px; min-width: 30px; background-color: #2bb86c; font-size: 12px; font-weight: 500; color: #FFFFFF; justify-content: center; align-items: center; }Feel free to customize it or use your own stylesheet.
4. Creating the Poll and Voting System with PHPWe can finally start programming our poll and voting system with PHP.
4.1. FunctionsThe functions.php file will contain the template and database connection functions, which we can implement in all the pages that we create.
Edit the functions.php file and add: