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. But if you want to create your own poll and voting system, this tutorial will help you a lot.

This tutorial will explore how to build a simple poll script in PHP. We’ll use PHP and MySQL to create a poll system without JavaScript or jQuery. Also, our voting script uses PHP and MySQL to store poll data, poll’s options and votes into the database.

Poll Script Functionality

Poll and options data is stored into 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, we’ll use PHP COOKIE to restrict the user to submit the vote for multiple times. Poll result with total votes count and votes on each option will display in the result page. The result of poll’s options will be shown as percentage bar.

Database Tables Creation

The poll system is used 3 MySQL database tables, polls, poll_options, and poll_votes.

The polls table contains poll subject or question.

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 table contains poll’s options and respective poll id.

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;

Insert poll and respective options data into the database for demonstration purpose.

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 is used to handle all the request for the entire poll and voting system. This class does the following works.
__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 ''){
        
$data '';
        
$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)

This file display the poll question and respective options. For selecting an option a radio button is placed with each option label. At the bottom, a submit button is provided to submit the vote and a link to view the result of the poll.

<?php
    
//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, vote is inserted using Poll class. Also, PHP COOKIE is used to signify the user has voted and status is shown to the user.

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

//Check whether vote is submitted
if(isset($_POST['voteSubmit'])){
    
$voteData = array(
        
'poll_id' => $_POST['pollID'],
        
'poll_option_id' => $_POST['voteOpt']
    );
    
//Submit vote by Poll class
    
$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.php';
$poll = new Poll;
?> <?php
//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;
}

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

#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’re tried to show the process of creating web poll system with PHP and MySQL. You can easily extend this simple PHP poll and voting system script as per your requirement. However this online voting tutorial helps to understand online polling system and build your own web poll using PHP and MySQL.

1 Comment

  1. Clasificados Cuba Said...

Leave a reply

Connect With CodexWorld