In this tutorial, we are going to explore how to create a simple poll system in PHP. This voting system will be purely using PHP without JavaScript client side enhancement. Its purpose is to demonstrate how we can use OOP style coding to create such as system. It is not made for production environment, for a real production ready pool system, you should extend it to use JavaScript to improve its user experience.
We will need storage to store voter's votes as well as poll's options. In this case, we will use MySQL as our storage. We will have table "options" to keep available poll options, and table "voters" to keep voters' information ( ip in our case). We assume you have experience of using MySQL, so create database tables as below:
CREATE TABLE `options` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 250 ) NOT NULL
) ENGINE = InnoDB;
CREATE TABLE `voters` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`option_id` INT NOT NULL ,
`ip` VARCHAR( 250 ) NOT NULL ,
`number` INT NOT NULL
)
Then, for demonstration purpose, I will insert some data into table "options":
INSERT INTO `options` (`id` ,`name`)VALUES (NULL , 'PHP'),
(NULL , 'JQuery'),
(NULL , 'C++'),
(NULL , 'Java');
As I have mentioned earlier, our approach is implement this system is OOP. So let us take a look at the PHP object class "Vote":
<?php
/**
*@author The-Di-Lab
*@email thedilab@gmail.com
*@website www.the-di-lab.com
*@version 1.0
**/
class Vote {
private $_host = 'localhost';
private $_database = 'vote_system';
private $_dbUser = 'root';
private $_dbPwd = '';
private $_con = false;
private $_optionTable = 'options';
private $_voterTable = 'voters';
/**
* Constructor
*/
public function __construct()
{
if(!$this->_con)
{
$this->_con = mysql_connect($this->_host,$this->_dbUser,$this->_dbPwd);
if(!$this->_con){
die('Could not connect: ' . mysql_error());
}
mysql_select_db($this->_database,$this->_con)|| die('Could not select database: ' . mysql_error());
}
}
//private functions
private function _query($sql)
{
$result = mysql_query($sql,$this->_con);
if(!$result){
die('unable to query'. mysql_error());
}
$data= array();
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
$data[]=$row;
}
return $data;
}
private function _alreadyVote($ip)
{
$sql = 'SELECT * FROM '.$this->_voterTable.' WHERE ip="'.$ip.'"';
$result = $this->_query($sql);
return sizeof($result)>0;
}
//public functions
public function vote($optionId)
{
$ip = $_SERVER['REMOTE_ADDR'];
if(!$this->_alreadyVote($ip)){
$sql ='INSERT INTO '.$this->_voterTable.' (id,option_id,ip) '.' VALUES(NULL,"'.mysql_real_escape_string($optionId).'","'.mysql_real_escape_string($ip).'")';
$result = mysql_query($sql,$this->_con);
if(!$result){
die('unable to insert'. mysql_error());
}
}
}
public function getList()
{
$sql = 'SELECT * FROM '.$this->_optionTable;
return $this->_query($sql);
}
public function showResults()
{
$sql =
'SELECT * FROM '.$this->_optionTable.' LEFT JOIN '.'(SELECT option_id, COUNT(*) as number FROM '.$this->_voterTable.' GROUP BY option_id) as votes'.
' ON '.$this->_optionTable.'.id = votes.option_id';
return $this->_query($sql);
}
public function getTotal()
{
$sql = 'SELECT count(*)as total FROM '.$this->_voterTable;
return $this->_query($sql);
}
}
?>
Firstly, let us take a look at variables in this class:
private $_host: Host url for MySQL connection.
private $_database: MySQL database name.
private $_dbUser: MySQL database user name.
private $_dbPwd: MySQL database user password.
private $_con: This stores MySQL connection. And it is created once per object.
private $_optionTable: options' table name. This makes life easy if you want to use other name instead of "options".
private $_voterTable: voters' table name.This makes life easy if you want to use other name instead of "voters".
This class is very straight forward if you have some PHP coding knowledge. There four public functions:
public function vote($optionId): This function will vote for option with $optionId and it gets voter's ip using $_SERVER['REMOTE_ADDR'].
public function getList(): This function get array of available options with id and name fields.
public function showResults(): This function runs a left join to get array of options with its voting results.
public function getTotal(): This function returns total number of votes for this poll.
Poll page is the actual front page where we make sure of Vote class to implement a poll system.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<style>
ul{
width:300px;
list-style-type: none;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 12px;
line-height: 2em;
}
ul li{
margin-bottom:2px;
padding:2px;
}
ul li.result{
position: relative;
}
ul li.result span.bar{
background-color: #D8DFEA;
display: block;
left: 0;
position: absolute;
top: 0;
z-index: -1;
}
</style>
</head>
<body>
<?php
// ************************1
include 'vote.php';
$vote = new Vote();
$action='';
//get action ************************2
if(isset($_REQUEST['action'])){
$action = $_REQUEST['action'];
}
//vote and show results ************************3
if('vote'==$action){
//vote ************************4
$vote->vote($_REQUEST['id']);
//show results ************************5
$total=$vote->getTotal();
// ************************6
echo '<ul>';
foreach($vote->showResults() as $vote){
$percent = 0;
if(isset($vote['number'])&&!empty($vote['number'])){
$percent = $vote['number']/$total * 100;
}
echo '<li class="result">';
echo '<span class="bar" style="width:'.$percent.'%;"> </span>';
echo '<span class="label">'.$vote['name'].' (<strong>'.$percent.'%</strong>)</span>';
echo '</li>';
}
echo '</ul>';
//show options ************************7
}else{
echo '<ul>';
foreach($vote->getList() as $option){
echo '<li>';
echo '<a href="'.$_SERVER['PHP_SELF'].'?action=vote&&id='.$option['id'].'">'.$option['name'].'</a>';
echo '</li>';
}
echo '</ul>';
}
?>
</body>
</html>
You can download this script from my github account.
Thank you for reading this article, and if you have any encountered anything different, have a different solution or think our solution is wrong, do let us know in the comment section. We will be very happy to hear that.
If you like our tutorial, please follow us on Twitter and help spread the word. We need your support to continue.