Online Poll and Voting System with PHP and MySQL

Online poll mainly used to identify the choice of web users. Online survey or poll is mostly used on the web today, and there are many services are available which provides a built-in poll system. However, you can easily implement the online voting system using PHP and MySQL. If you want to create your own poll and voting system, this tutorial will help you to create a simple, clean polling or voting system using PHP.

In this tutorial, we will show you how to build a simple poll script in PHP. The example script uses PHP and MySQL to create a poll system without any JavaScript or jQuery. Also, this voting script store poll data, poll’s options and votes into the database using PHP and MySQL.

Poll Script Functionality

Poll and options data is stored in the MySQL database. Poll question and respective options will be fetched from the database and shown to the user. The user can be able to select an option and submit their vote. Once the vote is submitted, it will be stored in the database with the respective poll option. Also, PHP COOKIE will be used to restrict the user to submit the vote for multiple times. The poll result with total votes count and votes on each option will display on the result page. The result of poll’s options will be shown as percentage bar.

Create Database Tables

The poll system required 3 tables in MySQL database, polls, poll_options, and poll_votes.

The poll information is stored in the polls table, like the poll subject, status, etc.

CREATE TABLE `polls` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `subject` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 `created` datetime NOT NULL,
 `modified` datetime NOT NULL,
 `status` enum('1','0') COLLATE utf8_unicode_ci NOT NULL DEFAULT '1',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

The poll options associated with the respective poll are stored in the poll_options table.

CREATE TABLE `poll_options` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `poll_id` int(11) NOT NULL,
 `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 `created` datetime NOT NULL,
 `modified` datetime NOT NULL,
 `status` enum('1','0') COLLATE utf8_unicode_ci NOT NULL DEFAULT '1',
 PRIMARY KEY (`id`),
 KEY `poll_id` (`poll_id`),
 CONSTRAINT `poll_options_ibfk_1` FOREIGN KEY (`poll_id`) REFERENCES `polls` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

The poll_votes table contains votes count of the poll option, respective option id, and poll id.

CREATE TABLE `poll_votes` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `poll_id` int(11) NOT NULL,
 `poll_option_id` int(11) NOT NULL,
 `vote_count` bigint(10) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `poll_id` (`poll_id`),
 KEY `poll_option_id` (`poll_option_id`),
 CONSTRAINT `poll_votes_ibfk_1` FOREIGN KEY (`poll_id`) REFERENCES `polls` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION,
 CONSTRAINT `poll_votes_ibfk_2` FOREIGN KEY (`poll_option_id`) REFERENCES `poll_options` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

For the demonstration purpose, insert some test data (poll and respective options) in the database.

INSERT INTO `polls` (`id`, `subject`, `created`, `modified`, `status`) VALUES
(1, 'Which is Your Favorite Website for PHP Programming?', '2016-11-07 04:13:13', '2016-11-07 04:13:13', '1');
INSERT INTO `poll_options` (`id`, `poll_id`, `name`, `created`, `modified`, `status`) VALUES
(1, 1, 'CodexWorld', '2016-11-07 11:29:31', '2016-11-07 11:29:31', '1'),
(2, 1, 'SitePoint', '2016-11-07 11:29:31', '2016-11-07 11:29:31', '1'),
(3, 1, 'Envato Tuts+', '2016-11-07 11:29:31', '2016-11-07 11:29:31', '1'),
(4, 1, 'Others', '2016-11-08 08:20:25', '2016-11-08 08:20:25', '1');

Poll Class

The Poll class handles all the operations related to the database. For example, connect to the MySQL database server, insert, update, and delete records in the database. Specify the database host ($dbHost), username ($dbUser), password ($dbPwd), and name ($dbName) as per your database server credentials.

  • __construct() – Connects and select the database.
  • getQuery() – Executes the SQL query on MySQL database and returns the data. It is a private function used only in this class.
  • getPolls() – Fetch the poll and respective options. Also, it can fetch the multiple polls data based on the request.
  • vote() – Inserts or updates the vote count into the database.
  • getResult() – Provides Poll result with votes count of poll’s options.
<?php
/*
 * Poll Management Class
 * This class is used to manage the online poll & voting system
 * @author    CodexWorld.com
 * @url       http://www.codexworld.com
 * @license   http://www.codexworld.com/license
 */
class Poll{
    private 
$dbHost  'localhost';
    private 
$dbUser  'root';
    private 
$dbPwd   '';
    private 
$dbName  'poll_system';            
    private 
$db      false;
    private 
$pollTbl 'polls';
    private 
$optTbl  'poll_options';
    private 
$voteTbl 'poll_votes';
    
    public function 
__construct(){
        if(!
$this->db){ 
            
// Connect to the database
            
$conn = new mysqli($this->dbHost$this->dbUser$this->dbPwd$this->dbName);
            if(
$conn->connect_error){
                die(
"Failed to connect with MySQL: " $conn->connect_error);
            }else{
                
$this->db $conn;
            }
        }
    }
    
    
/*
     * Runs query to the database
     * @param string SQL
     * @param string count, single, all
     */
    
private function getQuery($sql,$returnType ''){
        
$result $this->db->query($sql);
        if(
$result){
            switch(
$returnType){
                case 
'count':
                    
$data $result->num_rows;
                    break;
                case 
'single':
                    
$data $result->fetch_assoc();
                    break;
                default:
                    if(
$result->num_rows 0){
                        while(
$row $result->fetch_assoc()){
                            
$data[] = $row;
                        }
                    }
            }
        }
        return !empty(
$data)?$data:false;
    }
    
    
/*
     * Get polls data
     * Returns single or multiple poll data with respective options
     * @param string single, all
     */
    
public function getPolls($pollType 'single'){
        
$pollData = array();
        
$sql "SELECT * FROM ".$this->pollTbl." WHERE status = '1' ORDER BY created DESC";
        
$pollResult $this->getQuery($sql$pollType);
        if(!empty(
$pollResult)){
            if(
$pollType == 'single'){
                
$pollData['poll'] = $pollResult;
                
$sql2 "SELECT * FROM ".$this->optTbl." WHERE poll_id = ".$pollResult['id']." AND status = '1'";
                
$optionResult $this->getQuery($sql2);
                
$pollData['options'] = $optionResult;
            }else{
                
$i 0;
                foreach(
$pollResult as $prow){
                    
$pollData[$i]['poll'] = $prow;
                    
$sql2 "SELECT * FROM ".$this->optTbl." WHERE poll_id = ".$prow['id']." AND status = '1'";
                    
$optionResult $this->getQuery($sql2);
                    
$pollData[$i]['options'] = $optionResult;
                }
            }
        }
        return !empty(
$pollData)?$pollData:false;
    }
    
    
/*
     * Submit vote
     * @param array of poll option data
     */
    
public function vote($data = array()){
        if(!isset(
$data['poll_id']) || !isset($data['poll_option_id']) || isset($_COOKIE[$data['poll_id']])) {
            return 
false;
        }else{
            
$sql "SELECT * FROM ".$this->voteTbl." WHERE poll_id = ".$data['poll_id']." AND poll_option_id = ".$data['poll_option_id'];
            
$preVote $this->getQuery($sql'count');
            if(
$preVote 0){
                
$query "UPDATE ".$this->voteTbl." SET vote_count = vote_count+1 WHERE poll_id = ".$data['poll_id']." AND poll_option_id = ".$data['poll_option_id'];
                
$update $this->db->query($query);
            }else{
                
$query "INSERT INTO ".$this->voteTbl." (poll_id,poll_option_id,vote_count) VALUES (".$data['poll_id'].",".$data['poll_option_id'].",1)";
                
$insert $this->db->query($query);
            }
            return 
true;
        }
    }
    
    
/*
     * Get poll result
     * @param poll ID
     */
    
public function getResult($pollID){
        
$resultData = array();
        if(!empty(
$pollID)){
            
$sql "SELECT p.subject, SUM(v.vote_count) as total_votes FROM ".$this->voteTbl." as v LEFT JOIN ".$this->pollTbl." as p ON p.id = v.poll_id WHERE poll_id = ".$pollID;
            
$pollResult $this->getQuery($sql,'single');
            if(!empty(
$pollResult)){
                
$resultData['poll'] = $pollResult['subject'];
                
$resultData['total_votes'] = $pollResult['total_votes'];
                
$sql2 "SELECT o.id, o.name, v.vote_count FROM ".$this->optTbl." as o LEFT JOIN ".$this->voteTbl." as v ON v.poll_option_id = o.id WHERE o.poll_id = ".$pollID;
                
$optResult $this->getQuery($sql2);
                if(!empty(
$optResult)){
                    foreach(
$optResult as $orow){
                        
$resultData['options'][$orow['name']] = $orow['vote_count']; 
                    }
                }
            }
        }
        return !empty(
$resultData)?$resultData:false;
    }
}

Poll View (index.php)

Initially, the question and respective options are displayed. For selecting an option a radio button is placed with each option label. The user can use the submit button to provide their vote. Also, a link will be provided to view the result of the poll.

<?php
    //include and initialize Poll class 
    include 'Poll.class.php';
    $poll = new Poll;

    //get poll and options data
    
$pollData $poll->getPolls();
?> <div class="pollContent">     <?php echo !empty($statusMsg)?'<p class="stmsg">'.$statusMsg.'</p>':''?> <form action="" method="post" name="pollFrm"> <h3><?php echo $pollData['poll']['subject']; ?></h3> <ul>         <?php foreach($pollData['options'] as $opt){
            echo 
'<li><input type="radio" name="voteOpt" value="'.$opt['id'].'" >'.$opt['name'].'</li>';
        } 
?> </ul> <input type="hidden" name="pollID" value="<?php echo $pollData['poll']['id']; ?>"> <input type="submit" name="voteSubmit" class="button" value="Vote"> <a href="results.php?pollID=<?php echo $pollData['poll']['id']; ?>">Results</a> </form> </div>

Once the chosen option is submitted, the vote is inserted in the poll_votes table via Poll class. Also, PHP COOKIE is used to signify the user has voted and the vote submission status is shown to the user.

<?php
//if vote is submitted
if(isset($_POST['voteSubmit'])){
    
$voteData = array(
        
'poll_id' => $_POST['pollID'],
        
'poll_option_id' => $_POST['voteOpt']
    );
    
//insert vote data
    
$voteSubmit $poll->vote($voteData);
    if(
$voteSubmit){
        
//store in $_COOKIE to signify the user has voted
        
setcookie($_POST['pollID'], 1time()+60*60*24*365);
        
        
$statusMsg 'Your vote has been submitted successfully.';
    }else{
        
$statusMsg 'Your vote already had submitted.';
    }
}
?>

Poll Result (results.php)

In this file, poll result is fetched from the database and result details are shown to the user. Votes count for each option is converted to percentage format and appears as a percentage bar.

<?php
//include and initialize Poll class 
include 'Poll.class.php';
$poll = new Poll;

//get poll result data
$pollResult $poll->getResult($_GET['pollID']);
?> <h3><?php echo $pollResult['poll']; ?></h3> <p><b>Total Votes:</b> <?php echo $pollResult['total_votes']; ?></p> <?php
if(!empty($pollResult['options'])){ $i=0;
    
//Option bar color class array
    
$barColorArr = array('azure','emerald','violet','yellow','red');
    
//Generate option bars with votes count
    
foreach($pollResult['options'] as $opt=>$vote){
        
//Calculate vote percent
        
$votePercent round(($vote/$pollResult['total_votes'])*100);
        
$votePercent = !empty($votePercent)?$votePercent.'%':'0%';
        
//Define bar color class
        
if(!array_key_exists($i$barColorArr)){
            
$i=0;
        }
        
$barColor $barColorArr[$i];
?> <div class="bar-main-container <?php echo $barColor?>"> <div class="txt"><?php echo $opt?></div> <div class="wrap"> <div class="bar-percentage"><?php echo $votePercent?></div> <div class="bar-container"> <div class="bar" style="width: <?php echo $votePercent?>;"></div> </div> </div> </div> <?php $i++; } } ?> <a href="index.php">Back To Poll</a>

CSS Code

In the index.php file, following CSS is used to styling poll subject and options.

.pollContent{
    float: left;
    width: 500px;
}
.pollContent h3 {
    font-size: 18px;
    color: #333;
    text-align: left;
    float: left;
    border-bottom: 2px solid #333;
    width: 100%;
    margin: 0 auto;
    padding-bottom: 10px;
}
.pollContent ul{
    list-style: none;
    float: left;
    width: 100%;
    padding: 10px;
}
.pollContent input[type="submit"], .pollContent a{
    border: none;
    font-size: 16px;
    color: #fff;
    border-radius: 3px;
    padding: 10px 15px 10px 15px; 
    background-color: #34a853;
    text-decoration: none;
    cursor: pointer;
}
.stmsg{font-size: 16px;color:#FBBC05;}

In the results.php file, following CSS is used to styling poll result percentage bars.

#container { text-align: center; margin: 20px; }
h2 { color: #CCC; }
a { text-decoration: none; color: #EC5C93; }
.bar-main-container {
    margin: 10px auto;
    width: 300px;
    height: 55px;
    -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    border-radius: 4px;
    font-family: sans-serif;
    font-weight: normal;
    font-size: 0.8em;
    color: #FFF;
}
.wrap { padding: 8px; }
.bar-percentage {
    float: left;
    background: rgba(0,0,0,0.13);
    -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    border-radius: 4px;
    padding: 9px 0px;
    width: 18%;
    height: 16px;
    margin-top: -15px;
}
.bar-container {
    float: right;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
    height: 10px;
    background: rgba(0,0,0,0.13);
    width: 78%;
    margin: 0px 0px;
    overflow: hidden;
}
.bar-main-container .txt{
    padding-top: 5px;
    font-size: 16px;
    font-weight: bold;
}

.bar {
    float: left;
    background: #FFF;
    height: 100%;
    -webkit-border-radius: 10px 0px 0px 10px;
    -moz-border-radius: 10px 0px 0px 10px;
    border-radius: 10px 0px 0px 10px;
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
    filter: alpha(opacity=100);
    -moz-opacity: 1;
    -khtml-opacity: 1;
    opacity: 1;
}

/* COLORS */
.azure   { background: #38B1CC; }
.emerald { background: #2CB299; }
.violet  { background: #8E5D9F; }
.yellow  { background: #EFC32F; }
.red     { background: #E44C41; }

Conclusion

Here we’ve tried to show the web poll system creation process with PHP and MySQL. Hope this online voting tutorial helps to understand online polling system and build your own web poll using PHP and MySQL. Also, you can easily extend this simple PHP poll and voting system script as per your requirement.

Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request

13 Comments

  1. Navya Nimisha Das Said...
  2. Andy Said...
  3. Alutech Said...
  4. Sabry Said...
  5. Arfan Said...
  6. Hakeem Said...
  7. Stella Allets Said...
    • CodexWorld Said...
  8. Ritu Dhakal Said...
    • CodexWorld Said...
  9. Akash Aher Said...
  10. Daishonen Said...
  11. Clasificados Cuba Said...

Leave a reply

keyboard_double_arrow_up