HTML CSS JavaScript jQuery PHP Python MySQL

Poll and Voting System with PHP and MySQL

Updated on by David Adams

Poll and Voting System with PHP and MySQL

In this tutorial we'll be creating a complete poll and voting system with PHP and MySQL, you'll learn how to create polls, implement a voting system, delete polls, and view the list of created polls.

Each poll we create can have an unlimited amount of answers we can add to it, these answers will be voted by our visitors/users and then they can view the results once voted, each vote a user makes will be updated in our database.

The Basic and Advanced packages include additional features and a download link to the source code.

1. Getting Started

Before we jump into programming our Poll and Voting system there are a few requirements that need to be met and we need to 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 contain answers, users will be able to vote and view the result.
  • MySQL Database Interaction — Interact with our database with PHP, the polls we create will be stored in our database.
  • Basic Template System — We'll create a basic template system for our app, the template system will contain the header and footer sections, these will be used for every page we create (so we don't have to write the same code over and over).

1.2. Requirements

  • Download and install XAMPP, XAMPP is a web server that includes the essentials for web developers (PHP, MySQL, Apache, etc), if you already have a web server set-up with PHP & MySQL then you can skip this step.

1.3. File Structure & Setup

Create the following files and folders below in the htdocs folder (XAMPP), usually located at C:\xampp\htdocs.

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 polls created and the navigation buttons.
  • create.php — The create page will contain input fields (HTML5) so we can create new polls.
  • vote.php — The vote page will show the list of answers for the specified poll, each answer will contain a radio button so the user can select an answer and vote.
  • result.php — The result page will show the results for the specified poll, 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 Tables

If you have installed XAMPP you can create the MySQL database with phpMyAdmin, just make sure you start your web server, open the XAMPP control panel and click Start for both Apache and MySQL.

  • Navigate 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,
	`desc` text NOT NULL,
	PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

INSERT INTO `polls` (`id`, `title`, `desc`) VALUES (1, 'What''s your favorite 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, 'Java', 0);

A visual representation of the "phppoll" database:

MySQL Poll Database

Description of each table and the columns in those tables:

  • polls table — This table will contain information about the polls we create (title and description).
    • id — The unique ID for the poll, this will be auto incremented.
    • title — The title of the poll, this could be a question, etc.
    • desc — The description of the poll, this is optional, you do not need to provide a description.
  • poll_answers table — This table will contain all the answers for our created polls.
    • id — Unique ID, this will be auto incremented.
    • poll_id — The poll ID, this will be the id column in the polls table, this 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 on the database on the left side navigation panel, you should see something like this:

phpMyAdmin Poll Database

3. Creating the Stylesheet (CSS3)

The stylesheet will make our poll and voting system more appealing, add the below CSS code to style.css:

* {
      box-sizing: border-box;
      font-family: -apple-system, BlinkMacSystemFont, "segoe ui", roboto, oxygen, ubuntu, cantarell, "fira sans", "droid sans", "helvetica neue", Arial, sans-serif;
      font-size: 16px;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
}
body {
      background-color: #FFFFFF;
      margin: 0;
}
.navtop {
      background-color: #3f69a8;
      height: 60px;
      width: 100%;
      border: 0;
}
.navtop div {
      display: flex;
      margin: 0 auto;
      width: 1000px;
      height: 100%;
}
.navtop div h1, .navtop div a {
      display: inline-flex;
      align-items: center;
}
.navtop div h1 {
      flex: 1;
      font-size: 24px;
      padding: 0;
      margin: 0;
      color: #ecf0f6;
      font-weight: normal;
}
.navtop div a {
      padding: 0 20px;
      text-decoration: none;
      color: #c5d2e5;
      font-weight: bold;
}
.navtop div a i {
      padding: 2px 8px 0 0;
}
.navtop div a:hover {
      color: #ecf0f6;
}
.content {
      width: 1000px;
      margin: 0 auto;
}
.content h2 {
      margin: 0;
      padding: 25px 0;
      font-size: 22px;
      border-bottom: 1px solid #ebebeb;
      color: #666666;
}
.home .create-poll {
      display: inline-block;
      text-decoration: none;
      background-color: #38b673;
      font-weight: bold;
      font-size: 14px;
      border-radius: 5px;
      color: #FFFFFF;
      padding: 10px 15px;
      margin: 15px 0;
}
.home .create-poll:hover {
      background-color: #32a367;
}
.home table {
      width: 100%;
      padding-top: 30px;
      border-collapse: collapse;
}
.home table thead {
      background-color: #ebeef1;
      border-bottom: 1px solid #d3dae0;
}
.home table thead td {
      padding: 10px;
      font-weight: bold;
      color: #767779;
      font-size: 14px;
}
.home table tbody tr {
      border-bottom: 1px solid #d3dae0;
}
.home table tbody tr:nth-child(even) {
      background-color: #fbfcfc;
}
.home table tbody tr:hover {
      background-color: #376ab7;
}
.home table tbody tr:hover td {
      color: #FFFFFF;
}
.home table tbody tr:hover td:nth-child(1) {
      color: #FFFFFF;
}
.home table tbody tr td {
      padding: 10px;
}
.home table tbody tr td:nth-child(1) {
      color: #a5a7a9;
}
.home table tbody tr td.actions {
      padding: 8px;
      text-align: right;
}
.home table tbody tr td.actions .view, .home table tbody tr td.actions .edit, .home table tbody tr td.actions .trash {
      display: inline-flex;
      text-align: right;
      text-decoration: none;
      color: #FFFFFF;
      padding: 10px 12px;
      border-radius: 5px;
}
.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 .edit {
      background-color: #37afb7;
}
.home table tbody tr td.actions .edit:hover {
      background-color: #319ca3;
}
.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;
}
.update form input, .update form textarea {
      padding: 10px;
      width: 100%;
      margin-right: 25px;
      margin-bottom: 15px;
      border: 1px solid #cccccc;
}
.update form textarea {
      height: 200px;
}
.update form input[type="submit"] {
      display: block;
      background-color: #38b673;
      border: 0;
      font-weight: bold;
      font-size: 14px;
      color: #FFFFFF;
      cursor: pointer;
      width: 200px;
      margin-top: 15px;
      border-radius: 5px;
}
.update form input[type="submit"]:hover {
      background-color: #32a367;
}
.delete .yesno {
      display: flex;
}
.delete .yesno a {
      display: inline-block;
      text-decoration: none;
      background-color: #38b673;
      font-weight: bold;
      color: #FFFFFF;
      padding: 10px 15px;
      margin: 15px 10px 15px 0;
      border-radius: 5px;
}
.delete .yesno a:hover {
      background-color: #32a367;
}
.poll-vote form {
      display: flex;
      flex-flow: column;
}
.poll-vote form label {
      padding-bottom: 10px;
}
.poll-vote form input[type="radio"] {
      transform: scale(1.1);
}
.poll-vote form input[type="submit"], .poll-vote form a {
      display: inline-block;
      padding: 8px;
      border-radius: 5px;
      background-color: #38b673;
      border: 0;
      font-weight: bold;
      font-size: 14px;
      color: #FFFFFF;
      cursor: pointer;
      width: 150px;
      margin-top: 15px;
}
.poll-vote form input[type="submit"]:hover, .poll-vote form a:hover {
      background-color: #32a367;
}
.poll-vote form a {
      text-align: center;
      text-decoration: none;
      background-color: #37afb7;
      margin-left: 5px;
}
.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: 5px;
}
.poll-result .wrapper .poll-question p {
      margin: 0;
      padding: 5px 0;
}
.poll-result .wrapper .poll-question p span {
      font-size: 14px;
}
.poll-result .wrapper .poll-question .result-bar {
      display: flex;
      height: 25px;
      min-width: 5%;
      background-color: #38b673;
      border-radius: 5px;
      font-size: 14px;
      color: #FFFFFF;
      justify-content: center;
      align-items: center;
}

Feel free to customize the stylesheet, or use your own stylesheet.

4. Creating the Poll and Voting System with PHP

We can finally start programming our poll and voting system with PHP.

4.1. Functions

The functions.php file will contain the template and database connection functions, this file will be included in every other PHP file we create.

Edit functions.php and add:

<?php
function pdo_connect_mysql() {
    // Update the details below with your MySQL details
    $DATABASE_HOST = 'localhost';
    $DATABASE_USER = 'root';
    $DATABASE_PASS = '';
    $DATABASE_NAME = 'phppoll';
    try {
    	return new PDO('mysql:host=' . $DATABASE_HOST . ';dbname=' . $DATABASE_NAME . ';charset=utf8', $DATABASE_USER, $DATABASE_PASS);
    } catch (PDOException $exception) {
    	// If there is an error with the connection, stop the script and display the error.
    	die ('Failed to connect to database!');
    }
}

Every time we want to connect to our MySQL database all we have to do is execute the above function, like the following;

pdo_connect_mysql();

If you cannot connect to MySQL you will probably need to update the variables in the MySQL connection function above, if you're using XAMPP you shouldn't need to update them.

Add after:

// Template header, feel free to customize this
function template_header($title) {
echo <<<EOT
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>$title</title>
		<link href="style.css" rel="stylesheet" type="text/css">
		<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
	</head>
	<body>
    <nav class="navtop">
    	<div>
    		<h1>Voting & Poll System</h1>
            <a href="index.php"><i class="fas fa-poll-h"></i>Polls</a>
    	</div>
    </nav>
EOT;
}

The header function for our templates, this includes the head section of the document and the top navigation bar that will appear on every page, we also include Font Awesome, this is a free icon library (icons we'll be using in our app).

Add after:

// Template footer
function template_footer() {
echo <<<EOT
    </body>
</html>
EOT;
}

The template footer function, this is basically the end of the document, closing the HTML tags, etc.

So now if we wanted to create a new page, we could do something like this:

<?php
// examplepage.php
include 'functions.php';
$pdo = pdo_connect_mysql();
?>

<?=template_header('Example Page')?>

<p>Hello World! Welcome to my custom page!</p>

<?=template_footer()?>

Awesome, right? Now we don't have to include the same template function code and connection function code in all our PHP files, all we have to do is execute the function.

Take note, the following code:

<?=template_footer()?>

Is the short version of:

<?php echo template_footer(); ?>

That's all the functions created that we're going to be using.

4.2. Index Page

The index page is basically just the home page for our poll and voting system, the index page will contain the list of polls that have been created.

Edit index.php and add:

<?php
include 'functions.php';
// Connect to MySQL
$pdo = pdo_connect_mysql();
// MySQL query that selects all the polls and poll answers
$stmt = $pdo->query('SELECT p.*, GROUP_CONCAT(pa.title ORDER BY pa.id) AS answers FROM polls p LEFT JOIN poll_answers pa ON pa.poll_id = p.id GROUP BY p.id');
$polls = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>

This will select all the polls and poll answers in our database tables, this is so we can display them in an HTML table.

Add after:

<?=template_header('Polls')?>

<div class="content home">
	<h2>Polls</h2>
	<p>Welcome to the index page, you can view the list of polls below.</p>
	<a href="create.php" class="create-poll">Create Poll</a>
	<table>
        <thead>
            <tr>
                <td>#</td>
                <td>Title</td>
				<td>Answers</td>
                <td></td>
            </tr>
        </thead>
        <tbody>
            <?php foreach ($polls as $poll): ?>
            <tr>
                <td><?=$poll['id']?></td>
                <td><?=$poll['title']?></td>
				<td><?=$poll['answers']?></td>
                <td class="actions">
					<a href="vote.php?id=<?=$poll['id']?>" class="view" title="View Poll"><i class="fas fa-eye fa-xs"></i></a>
                    <a href="delete.php?id=<?=$poll['id']?>" class="trash" title="Delete Poll"><i class="fas fa-trash fa-xs"></i></a>
                </td>
            </tr>
            <?php endforeach; ?>
        </tbody>
    </table>
</div>

<?=template_footer()?>

We start the above by executing the template header function (template_header()), after that, we iterate the polls using a foreach loop and display them in an HTML table, we then end the template with the template footer function (template_footer()).

With the HTML links in the table you can see we're going to pass the parameters onto the files (using a GET request): vote.php and delete.php, this how the PHP code will know which poll the user has clicked in the table.

If we navigate to http://localhost/phppoll/index.php we should see the following:

http://localhost/phppoll/index.php
PHP Poll Table List

We can now view the list of polls created, the links/buttons on this page will not show anything yet because we haven't created the other pages.

4.3. Create Page

This page we can use to create new polls using an HTML form and input fields, and on the server-side, we can use PHP and MySQL to insert new records into our database tables, for this to happen we first need do a POST request with PHP.

Edit create.php and add:

<?php
include 'functions.php';
$pdo = pdo_connect_mysql();
$msg = '';

We're going to need to use MySQL and use the template functions, so we must include the functions.php file, the $msg variable will be the output message to the user.

Add after:

// Check if POST data is not empty
if (!empty($_POST)) {
    // Post data not empty insert a new record
    // Check if POST variable "title" exists, if not default the value to blank, basically the same for all variables
    $title = isset($_POST['title']) ? $_POST['title'] : '';
    $desc = isset($_POST['desc']) ? $_POST['desc'] : '';
    // Insert new record into the "polls" table
    $stmt = $pdo->prepare('INSERT INTO polls VALUES (NULL, ?, ?)');
    $stmt->execute([$title, $desc]);
    // Below will get the last insert ID, this will be the poll id
    $poll_id = $pdo->lastInsertId();
    // Get the answers and convert the multiline string to an array, so we can add each answer to the "poll_answers" table
    $answers = isset($_POST['answers']) ? explode(PHP_EOL, $_POST['answers']) : '';
    foreach ($answers as $answer) {
        // If the answer is empty there is no need to insert
        if (empty($answer)) continue;
        // Add answer to the "poll_answers" table
        $stmt = $pdo->prepare('INSERT INTO poll_answers VALUES (NULL, ?, ?, 0)');
        $stmt->execute([$poll_id, $answer]);
    }
    // Output message
    $msg = 'Created Successfully!';
}
?>

The code above will only execute if the user has clicked the submit button in the HTML form, it's a POST request. If the POST variable is not empty then insert a new record into both our polls and poll_answers tables.

Not only can we insert new records but we're also securing the user input, prepared statements will prevent SQL injection.

Add After:

<?=template_header('Create Poll')?>

<div class="content update">
	<h2>Create Poll</h2>
    <form action="create.php" method="post">
        <label for="title">Title</label>
        <input type="text" name="title" id="title">
        <label for="desc">Description</label>
        <input type="text" name="desc" id="desc">
        <label for="answers">Answers (per line)</label>
        <textarea name="answers" id="answers"></textarea>
        <input type="submit" value="Create">
    </form>
    <?php if ($msg): ?>
    <p><?=$msg?></p>
    <?php endif; ?>
</div>

<?=template_footer()?>

Remember the index template we created earlier? We use both the template header and footer functions to create a basic template.

The form that we have created above we can use to insert new records, the POST names in PHP are the input names in the above form, the forms method is set to post because we need to make a POST request.

Now if we click the Create Poll button on the index page we'll see the following:

http://localhost/phppoll/create.php
PHP Create Poll Form

That's all we need to do to insert new records into our database tables.

4.4. Vote Page

On this page, user's will be able to see the answers for a poll and vote, they can also see the result without voting.

Edit vote.php and add:

<?php
include 'functions.php';
// Connect to MySQL
$pdo = pdo_connect_mysql();
// If the GET request "id" exists (poll id)...
if (isset($_GET['id'])) {
    // MySQL query that selects the poll records by the GET request "id"
    $stmt = $pdo->prepare('SELECT * FROM polls WHERE id = ?');
    $stmt->execute([$_GET['id']]);
    // Fetch the record
    $poll = $stmt->fetch(PDO::FETCH_ASSOC);
    // Check if the poll record exists with the id specified
    if ($poll) {
        // MySQL query that selects all the poll answers
        $stmt = $pdo->prepare('SELECT * FROM poll_answers WHERE poll_id = ?');
        $stmt->execute([$_GET['id']]);
        // Fetch all the poll anwsers
        $poll_answers = $stmt->fetchAll(PDO::FETCH_ASSOC);
        // If the user clicked the "Vote" button...
        if (isset($_POST['poll_answer'])) {
            // Update and increase the vote for the answer the user voted for
            $stmt = $pdo->prepare('UPDATE poll_answers SET votes = votes + 1 WHERE id = ?');
            $stmt->execute([$_POST['poll_answer']]);
            // Redirect user to the result page
            header ('Location: result.php?id=' . $_GET['id']);
            exit;
        }
    } else {
        die ('Poll with that ID does not exist.');
    }
} else {
    die ('No poll ID specified.');
}
?>

For this page to work correctly the id param needs to be specified in the URL (vote.php?id=2, etc), this is what we call a GET request, if the id param exists we can fetch the records from our MySQL database by the id column (poll table) and the poll_id column (poll_answers table).

Not only do we make a GET request but we also make a POST request, if the user selects an answer and clicks the Vote button then our code will update the votes for that answer (MySQL UPDATE query) and redirect the user to the result page (result.php).

Add after:

<?=template_header('Poll Vote')?>

<div class="content poll-vote">
	<h2><?=$poll['title']?></h2>
	<p><?=$poll['desc']?></p>
    <form action="vote.php?id=<?=$_GET['id']?>" method="post">
        <?php for ($i = 0; $i < count($poll_answers); $i++): ?>
        <label>
            <input type="radio" name="poll_answer" value="<?=$poll_answers[$i]['id']?>"<?=$i == 0 ? ' checked' : ''?>>
            <?=$poll_answers[$i]['title']?>
        </label>
        <?php endfor; ?>
        <div>
            <input type="submit" value="Vote">
            <a href="result.php?id=<?=$poll['id']?>">View Result</a>
        </div>
    </form>
</div>

<?=template_footer()?>

The template above will iterate each answer and create the input radio fields we need for our form.

If we click the eye icon next to the test poll on the index page we'll see the following:

http://localhost/phppoll/vote.php?id=1
PHP Poll Vote Form

We can now vote on the polls we have created.

4.5. Result Page

This will be the page where the user will be able to view the poll result, the result will be sorted by the number of votes, the highest will be at the top.

Edit result.php and add:

<?php
include 'functions.php';
// Connect to MySQL
$pdo = pdo_connect_mysql();
// If the GET request "id" exists (poll id)...
if (isset($_GET['id'])) {
    // MySQL query that selects the poll records by the GET request "id"
    $stmt = $pdo->prepare('SELECT * FROM polls WHERE id = ?');
    $stmt->execute([$_GET['id']]);
    // Fetch the record
    $poll = $stmt->fetch(PDO::FETCH_ASSOC);
    // Check if the poll record exists with the id specified
    if ($poll) {
        // MySQL Query that will get all the answers from the "poll_answers" table ordered by the number of votes (descending)
        $stmt = $pdo->prepare('SELECT * FROM poll_answers WHERE poll_id = ? ORDER BY votes DESC');
        $stmt->execute([$_GET['id']]);
        // Fetch all poll answers
        $poll_answers = $stmt->fetchAll(PDO::FETCH_ASSOC);
        // Total number of votes, will be used to calculate the percentage
        $total_votes = 0;
        foreach ($poll_answers as $poll_answer) {
            // Every poll answers votes will be added to total votes
            $total_votes += $poll_answer['votes'];
        }
    } else {
        die ('Poll with that ID does not exist.');
    }
} else {
    die ('No poll ID specified.');
}
?>

Just like the voting page, we need to make a GET request that will get the poll ID (result.php?id=2, etc), and with that, we can get the poll results from our database ordered by the number of votes (descending).

Add after:

<?=template_header('Poll Results')?>

<div class="content poll-result">
	<h2><?=$poll['title']?></h2>
	<p><?=$poll['desc']?></p>
    <div class="wrapper">
        <?php foreach ($poll_answers as $poll_answer): ?>
        <div class="poll-question">
            <p><?=$poll_answer['title']?> <span>(<?=$poll_answer['votes']?> Votes)</span></p>
            <div class="result-bar" style= "width:<?=@round(($poll_answer['votes']/$total_votes)*100)?>%">
                <?=@round(($poll_answer['votes']/$total_votes)*100)?>%
            </div>
        </div>
        <?php endforeach; ?>
    </div>
</div>

<?=template_footer()?>

This template will iterate the answers and display them with the number of votes and a percentage bar.

Navigate to the test poll and you can either click Vote or click the View Results button, you should see something like this:

http://localhost/
PHP Poll Results

That's basically how you display the poll results and using a bit of CSS to display the percentage bar.

4.6. Delete Page

This page we'll use to delete polls, it will include a confirmation so we don't accidentally delete the wrong polls.

Edit delete.php and add:

<?php
include 'functions.php';
$pdo = pdo_connect_mysql();
$msg = '';
// Check that the poll ID exists
if (isset($_GET['id'])) {
    // Select the record that is going to be deleted
    $stmt = $pdo->prepare('SELECT * FROM polls WHERE id = ?');
    $stmt->execute([$_GET['id']]);
    $poll = $stmt->fetch(PDO::FETCH_ASSOC);
    if (!$poll) {
        die ('Poll doesn\'t exist with that ID!');
    }
    // Make sure the user confirms beore deletion
    if (isset($_GET['confirm'])) {
        if ($_GET['confirm'] == 'yes') {
            // User clicked the "Yes" button, delete record
            $stmt = $pdo->prepare('DELETE FROM polls WHERE id = ?');
            $stmt->execute([$_GET['id']]);
            // We also need to delete the answers for that poll
            $stmt = $pdo->prepare('DELETE FROM poll_answers WHERE poll_id = ?');
            $stmt->execute([$_GET['id']]);
            // Output msg
            $msg = 'You have deleted the poll!';
        } else {
            // User clicked the "No" button, redirect them back to the home/index page
            header('Location: index.php');
            exit;
        }
    }
} else {
    die ('No ID specified!');
}
?>

If the poll ID is specified and it exists in our polls table, we can confirm the user if they would like to delete the poll, if yes, the poll will be deleted, the poll answers will also be deleted from the poll_answers table.

Add after:

<?=template_header('Delete')?>

<div class="content delete">
	<h2>Delete Poll #<?=$poll['id']?></h2>
    <?php if ($msg): ?>
    <p><?=$msg?></p>
    <?php else: ?>
	<p>Are you sure you want to delete poll #<?=$poll['id']?>?</p>
    <div class="yesno">
        <a href="delete.php?id=<?=$poll['id']?>&confirm=yes">Yes</a>
        <a href="delete.php?id=<?=$poll['id']?>&confirm=no">No</a>
    </div>
    <?php endif; ?>
</div>

<?=template_footer()?>

This is the template for the delete page. If we navigate to the index page and click the trash icon next to one of our polls we'll see something like this:

http://localhost/phppoll/delete.php?id=1
PHP Poll Delete

Conclusion

You have now successfully created a poll and voting system with PHP and MySQL, congratulations!

What next? You could implement a login system that restricts certain users to create and delete polls, or add your own features to the poll and voting system.

If you enjoyed this article consider sharing it on social media websites, the more visitors we get the more quality content I can create.

If you would like to support us consider purchasing a package below, this will greatly help us create more tutorials and keep our server up and running.

Basic

Advanced

Source code
Database SQL file
Poll & Voting system
Index page
Create page
Vote page
Result page
Delete page
Update page
1 vote per user feature
Expires feature
SCSS file
Commented code
Free updates
Free support (bugs and minor issues)
* Payments are processed with PayPal.
* Both packages include the tutorial source code.
* Advanced package also includes the basic package.

$10.00

Download

$15.00

Download