首頁 >後端開發 >php教程 >PHP加MySQL投票系統的設計與實作分享

PHP加MySQL投票系統的設計與實作分享

不言
不言原創
2018-04-09 16:35:063472瀏覽

這篇文章要跟大家分享的是PHP加MySQL投票系統的設計與實作分享,有需要的朋友可以參考一下

php投票系統的設計與實現,需要的朋友可以參考下程式碼與資料庫結果設計,最後腳本之家提供了原始碼下載

系統不大,完成這個系統的過程我分了三個步驟
•資料庫設計
•系統框架設計
•前端美化

資料庫的設計
設計三張表:投票結果統計表(count_voting),投票者記錄表(ip_votes),用戶表(user)
投票結果統計表用於統計最後的投票記錄,我給它弄了4個字段:被投票項的名稱(SelectName),被投票項標籤名(LabelName)(起到分類的作用),票數(CountVotes) 。

投票人記錄表用於登記投票人的ip(IP),地理位置(Location),投票時間(VoteTime),被投票項名稱(SelectName)。然後我還給它加一個ID。

使用者表主要用於給管理員用的,包含使用者名稱(name)和密碼(passwd)。

產生表格的sql腳本如下:

複製程式碼 程式碼如下:

-- 
-- 表的结构 `count_voting` 
-- 
DROP TABLE IF EXISTS `count_voting`; 
CREATE TABLE IF NOT EXISTS `count_voting` ( 
`SelectName` varchar(40) NOT NULL, 
`LabelName` varchar(40) NOT NULL, 
`CountVotes` bigint(20) unsigned NOT NULL, 
UNIQUE KEY `SelectName` (`SelectName`), 
KEY `CountVotes` (`CountVotes`), 
KEY `CountVotes_2` (`CountVotes`), 
KEY `CountVotes_3` (`CountVotes`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='投票统计表'; 
-- -------------------------------------------------------- 
-- 
-- 表的结构 `ip_votes` 
-- 
DROP TABLE IF EXISTS `ip_votes`; 
CREATE TABLE IF NOT EXISTS `ip_votes` ( 
`ID` bigint(20) unsigned NOT NULL auto_increment COMMENT '投票人序号:自增', 
`IP` varchar(15) NOT NULL COMMENT '投票人IP', 
`Location` varchar(40) NOT NULL COMMENT '投票人位置', 
`VoteTime` datetime NOT NULL, 
`SelectName` varchar(40) NOT NULL, 
PRIMARY KEY (`ID`), 
KEY `ID` (`ID`), 
KEY `SelectName` (`SelectName`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ; 
-- 
-- 触发器 `ip_votes` 
-- 
DROP TRIGGER IF EXISTS `vote_count_after_insert_tr`; 
DELIMITER // 
CREATE TRIGGER `vote_count_after_insert_tr` AFTER INSERT ON `ip_votes` 
FOR EACH ROW UPDATE count_voting SET CountVotes = CountVotes + 1 WHERE SelectName = NEW.SelectName 
// 
DELIMITER ; 
-- -------------------------------------------------------- 
-- 
-- 表的结构 `user` 
-- 
DROP TABLE IF EXISTS `user`; 
CREATE TABLE IF NOT EXISTS `user` ( 
`name` varchar(10) NOT NULL COMMENT '管理员用户名', 
`passwd` char(32) NOT NULL COMMENT '登录密码MD5值' 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表'; 
-- 
-- 转存表中的数据 `user` 
-- 
INSERT INTO `user` (`name`, `passwd`) VALUES 
('ttxi', '700469ca1555900b18c641bf7b0a1fa1'), 
('jitttanwa', 'adac5659956d68bcbc6f40aa5cd00d5c'); 
-- 
-- 限制导出的表 
-- 
-- 
-- 限制表 `ip_votes` 
-- 
ALTER TABLE `ip_votes` 
ADD CONSTRAINT `ip_votes_ibfk_1` FOREIGN KEY (`SelectName`) REFERENCES `count_voting` (`SelectName`) ON DELETE CASCADE ON UPDATE CASCADE;

從腳本可以看出,我已經建立了一個觸發器,當往ip_votes表中插入資料的時候就給count_voting表中的CountVotes欄位加1。還能後出最後一句是設定外部關聯字。
框架設計
OperatorDB類別用於操作資料庫,OperatorVotingDB類別用於該系統特定的操作集合。
使用PDO操作資料庫,我它簡單的封裝一下:

複製程式碼 程式碼如下:

/** 
* 操作数据库 
* 封装PDO,使其方便自己的操作 
*/ 
class OperatorDB 
{ 
//连接数据库的基本信息 
private $dbms='mysql'; //数据库类型,对于开发者来说,使用不同的数据库,只要改这个. 
private $host='localhost'; //数据库主机名 
private $dbName='voting'; //使用的数据库 
private $user='voting'; //数据库连接用户名 
private $passwd='voting'; //对应的密码 
private $pdo=null; 
public function __construct() 
{ 
//dl("php_pdo.dll"); 
//dl("php_pdo_mysql.dll"); 
$this->dsn="$this->dbms:host=$this->host;dbname=$this->dbName"; 
try 
{ 
$this->conn=new PDO($this->dsn,$this->user,$this->passwd);//初始化一个PDO对象,就是创建了数据库连接对象$db 
} 
catch(PDOException $e) 
{ 
die("<br/>数据库连接失败(creater PDO Error!): ".$e->getMessage()."<br/>"); 
} 
} 
public function __destruct() 
{ 
$this->pdo = null; 
} 
public function exec($sql) 
{ 
} 
public function query($sql) 
{ 
} 
}


把連接資料庫的訊息封裝進去方便後續的操作。

複製程式碼 程式碼如下:

<?php 
require_once &#39;OperatorDB.php&#39;; 
class OperatorVotingDB 
{ 
private $odb; 
public function __construct() 
{ 
$this->odb = new OperatorDB(); 
} 
public function __destruct() 
{ 
$this->odb = null; 
} 
/** 
* 清空Voting数据中的所有表 
* 
* 调用数据库操作类,执行clear数据库的操作 
*/ 
public function clearTables() 
{ 
$sqls = array("TRUNCATE ip_votes;","TRUNCATE count_voting;"); 
$this->odb->exec($sqls[0]); 
$this->odb->exec($sqls[1]); 
} 
/** 
* 重置count_voting表中的CountValues字段为0 
* 
*/ 
public function resetCountValues() 
{ 
$sql = "UPDATE count_voting SET CountVotes = 0;"; 
$this->odb->exec($sql); 
} 
/** 
* 投票 
* 将信息写入ip_votes表 
* @param type $ip 
* @param type $loc 
* @param type $time 
* @param type $name 
*/ 
public function vote($ip,$loc,$name) 
{ 
$sql = "INSERT INTO ip_votes VALUES (NULL, &#39;$ip&#39;, &#39;$loc&#39;, NOW(), &#39;$name&#39;)"; 
$subsql = "SELECT MAX(to_days(VoteTime)) FROM ip_votes WHERE IP=&#39;$ip&#39;"; 
$stm = $this->odb->query($subsql); 
if (count($row=$stm->fetchAll())==1) 
{ 
$now = date("Y-m-d H:i:s"); 
$subsql = "SELECT to_days(&#39;$now&#39;);"; 
$stm = $this->odb->query($subsql)->fetch(); 
$time = $stm[0];//使用mysql计算出的today时间 
// echo $time."<br>"; 
// echo $row[0][0]; 
if ($time-$row[0][0]<1)//表中最大的时间和现在的时间$time比较 
{ 
echo "投票失败,相同ip需要隔一天才能投票"; 
return; 
} 
} 
// echo $sql; 
echo "投票成功!"; 
$this->odb->exec($sql); 
} 
/** 
* 添加SelectName字段的行 
* 
* @param string $name 
* @param string $label 
* @param int $count 
*/ 
public function addSelectName($name, $label, $count=0) 
{ 
$sql = "INSERT INTO count_voting VALUES (&#39;$name&#39;, &#39;$label&#39;, $count);"; 
$this->odb->exec($sql); 
} 
/** 
* 获取总投票情况,按票数排序的结果 
* 
* 按CountVotes字段排序,返回count_voting表 
* 
* @param int $n 
* 
*/ 
public function getVotesSortByCount($n=-1) 
{ 
$sql = "SELECT * FROM count_voting ORDER BY CountVotes DESC LIMIT 0 , $n;"; 
if (-1 == $n) 
{ 
$sql = "SELECT * FROM count_voting ORDER BY CountVotes DESC;"; 
} 
// echo $sql; 
return $this->odb->query($sql); 
} 
/** 
* 获取投票情况,按票数排序并按标签分组的结果 
* 
* 按CountVotes字段排序并按LabelName字段分组,返回count_voting表 
*/ 
public function getVotesGroupByLabel() 
{ 
$sql = "SELECT * FROM count_voting ORDER BY LabelName DESC;"; 
// echo $sql; 
return $this->odb->query($sql); 
} 
} 
?> 

下面还有需要的函数 
复制代码 代码如下:

<?php 
/** 
* 页面跳转函数 
* 使用js实现 
* @param string $url 
*/ 
function goToPgae($url) 
{ 
echo "<script language=&#39;javascript&#39; type=&#39;text/javascript&#39;>"; 
echo "window.location.href=&#39;$url&#39;"; 
echo "</script>"; 
} 
function jsFunc($fun, $arg=null) 
{ 
echo "<script language=&#39;javascript&#39; type=&#39;text/javascript&#39;>"; 
echo $fun."(&#39;$arg&#39;);"; 
echo "</script>"; 
} 
function jsFunc3($fun, $arg1=null,$arg2=null,$arg3=null) 
{ 
echo "<script language=&#39;javascript&#39; type=&#39;text/javascript&#39;>"; 
echo $fun."(&#39;$arg1&#39;,&#39;$arg2&#39;,&#39;$arg3&#39;);"; 
echo "</script>"; 
//echo $fun."(&#39;$arg1&#39;,&#39;$arg2&#39;,&#39;$arg3&#39;);"; 
} 
function isLoginNow() 
{ 
if ($_COOKIE["user"]==&#39;&#39;) 
{ 
return false; 
} 
return true; 
} 
function getClientIP() 
{ 
if ($_SERVER["HTTP_X_FORWARDED_FOR"]) 
{ 
if ($_SERVER["HTTP_CLIENT_IP"]) 
{ 
$proxy = $_SERVER["HTTP_CLIENT_IP"]; 
} 
else 
{ 
$proxy = $_SERVER["REMOTE_ADDR"]; 
} 
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"]; 
} 
else 
{ 
if ($_SERVER["HTTP_CLIENT_IP"]) 
{ 
$ip = $_SERVER["HTTP_CLIENT_IP"]; 
} 
else 
{ 
$ip = $_SERVER["REMOTE_ADDR"]; 
} 
} 
return $ip; 
} 
//从123查获取ip 
function getIpfrom123cha($ip) { 
$url = &#39;http://www.123cha.com/ip/?q=&#39;.$ip; 
$content = file_get_contents($url); 
$preg = &#39;/(?<=本站主数据:<\/li><li style=\"width:450px;\">)(.*)(?=<\/li>)/isU&#39;; 
preg_match_all($preg, $content, $mb); 
$str = strip_tags($mb[0][0]); 
//$str = str_replace(&#39; &#39;, &#39;&#39;, $str); 
$address = $str; 
if($address == &#39;&#39;) { 
$address = &#39;未明&#39;; 
} 
return $address; 
} 
//从百度获取ip所在地 
function getIpfromBaidu($ip) { 
$url = &#39;http://www.baidu.com/s?wd=&#39;.$ip; 
$content = file_get_contents($url); 
$preg = &#39;/(?<=<p class=\"op_ip_detail\">)(.*)(?=<\/p>)/isU&#39;; 
preg_match_all($preg, $content, $mb); 
$str = strip_tags($mb[0][1]); 
$str = str_replace(&#39; &#39;, &#39;&#39;, $str); 
$address = substr($str, 7); 
if($address == &#39;&#39;) { 
$address = &#39;未明&#39;; 
} 
return $address; 
} 
?>


#然後就是後台管理員的操作怎麼弄了,主要是新增投票項目的功能,操作資料庫上面已經實作。後面的基本上是頁面怎麼設置,關係到js。新增投票項目的頁面是動態的,如下:

複製程式碼 程式碼如下:

function addVote() 
{ 
right.innerHTML="<h2>添加投票项</h2>"; 
right.innerHTML+="<label>投票项标签<label>"; 
addInput("right","cLabelName","地区名"); 
right.innerHTML+="<br><label>投票项名称<label>"; 
addInput("right","cSelectName","学校名"); 
right.innerHTML+="<br>"; 
var args = &#39;\&#39;./add.php\&#39;,\&#39;cSelectName\&#39;,\&#39;cLabelName\&#39;&#39;; 
var str = &#39;<input type=button value="\u6dfb加" onclick="goToPage(&#39;+args+&#39;);"/>&#39;; 
right.innerHTML+=str; 
} 
//添加文本框 
function addInput(parent,id,pla) 
{ 
//创建input 
var input = document.createElement("input"); 
input.type = "text"; 
input.id = id; 
input.placeholder = pla; 
document.getElementById(parent).appendChild(input); 
}

效果:

PHP加MySQL投票系統的設計與實作分享

清空投票項也差不多,下過如下:

PHP加MySQL投票系統的設計與實作分享

#新增投票項是透過url傳遞變數到add.php頁面的。

複製程式碼 程式碼如下:

<?php 
require_once &#39;../api/func.php&#39;; 

if (!isLoginNow()) 
{ 
goToPgae("./index.php"); 
} 

$name = $_GET["cSelectName"]; 
$label = $_GET["cLabelName"]; 
//echo $name."<br>".$label; 
require_once &#39;../api/OperatorVotingDB.php&#39;; 
$ovdb=new OperatorVotingDB(); 
$ovdb->addSelectName($name,$label); 
require &#39;./header.htm&#39;; 
goToPgae("./admin.php?page=add&auto="."$label"."&id=cLabelName&foc=cSelectName&msg=添加成功"); 
?>

下面是兩個跳躍頁面的函數,js的(上面func.php中的跳到頁面函數也是透過js實現的)。

複製程式碼 程式碼如下:

//js 
function goToPage(url,arg1,arg2) 
{ 
var a = document.getElementById(arg1).value; 
var b = document.getElementById(arg2).value; 
url += &#39;?&#39;+arg1+&#39;=&#39;+a; 
url += &#39;&&#39;+arg2+&#39;=&#39;+b; 
window.location.href=url; 
} 

function goToPage1(url) 
{ 
window.location.href=url; 
}


#還有修改刪除功能沒有實作。我應該不會去實作那個了吧,js的話和新增功能差不多。

登入模組的話網上很多,模仿的。就是提交表單,查找資料庫,回傳結果。成功則設定cookie,後台的每個頁面都添加了檢測cookie的功能的。

前端美化
index.php頁面先操作資料庫取得投票項和票數,然後顯示出來(透過css p美化一下框架介面什麼的),最後點擊投票按鈕就提交表單,跳到vote.php頁面。

css的話我都是抄網路上的。我弄的效果如下:

PHP加MySQL投票系統的設計與實作分享

這個東西算是個很小的資訊管理系統吧,我已經把這個東西的原始碼放到github(https: //github.com/hanxi/voting)上去了,可以隨意下載修改也可以到腳本之家下載(點擊下載)。歡迎讀者回覆交流,這方面不是我的強項,有很多不足之處還望指教。

作者:涵曦(涵曦的技術部落格- 部落格園)
微博:t.qq.com/hanxi1203
來源:hanxi.cnblogs.com

#相關建議:

php設定php-fpm啟動參數及設定詳

#PHP 程式設計師的偵錯小結

######################################## ###################

以上是PHP加MySQL投票系統的設計與實作分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn