当前位置:首页 > 综合实例 > 列表

php投票系统简单实现源码

发布:smiling 来源: PHP粉丝网  添加日期:2014-08-28 16:11:59 浏览: 评论:0 

数据库的设计:设计三张表,投票结果统计表(count_voting),投票人记录表(ip_votes),用户表(user).

投票结果统计表用于统计最后的投票记录,我给它弄了4个字段:被投票项的名称(SelectName),被投票项标签名(LabelName)(起到分类的作用),票数(CountVotes).

投票人记录表用于登记投票人的ip(IP),地理位置(Location),投票时间(VoteTime),被投票项名称(SelectName),然后我还给它加一个ID.

用户表主要用于给管理员用的,包含用户名(name)和密码(passwd).

生成表的sql脚本如下,代码如下:

  1. -- 
  2. -- 表的结构 `count_voting` 
  3. -- 
  4.  
  5. DROP TABLE IF EXISTS `count_voting`; 
  6. CREATE TABLE IF NOT EXISTS `count_voting` ( 
  7.   `SelectName` varchar(40) NOT NULL
  8.   `LabelName` varchar(40) NOT NULL
  9.   `CountVotes` bigint(20) unsigned NOT NULL
  10.   UNIQUE KEY `SelectName` (`SelectName`), 
  11.   KEY `CountVotes` (`CountVotes`), 
  12.   KEY `CountVotes_2` (`CountVotes`), 
  13.   KEY `CountVotes_3` (`CountVotes`) 
  14. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='投票统计表'
  15.  
  16. -- -------------------------------------------------------- 
  17.  
  18. -- 
  19. -- 表的结构 `ip_votes` 
  20. -- 
  21.  
  22. DROP TABLE IF EXISTS `ip_votes`; 
  23. CREATE TABLE IF NOT EXISTS `ip_votes` ( 
  24.   `ID` bigint(20) unsigned NOT NULL auto_increment COMMENT '投票人序号:自增'
  25.   `IP` varchar(15) NOT NULL COMMENT '投票人IP'
  26.   `Location` varchar(40) NOT NULL COMMENT '投票人位置'
  27.   `VoteTime` datetime NOT NULL
  28.   `SelectName` varchar(40) NOT NULL
  29.   PRIMARY KEY  (`ID`), 
  30.   KEY `ID` (`ID`), 
  31.   KEY `SelectName` (`SelectName`) 
  32. ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ; 
  33.  
  34. -- 
  35. -- 触发器 `ip_votes` 
  36. -- 
  37. DROP TRIGGER IF EXISTS `vote_count_after_insert_tr`; 
  38. DELIMITER // 
  39. CREATE TRIGGER `vote_count_after_insert_tr` AFTER INSERT ON `ip_votes` 
  40.  FOR EACH ROW UPDATE count_voting SET CountVotes = CountVotes + 1 WHERE SelectName = NEW.SelectName 
  41. // 
  42. DELIMITER ; 
  43.  
  44. -- -------------------------------------------------------- 
  45.  
  46. -- 
  47. -- 表的结构 `user` 
  48. -- 
  49.  
  50. DROP TABLE IF EXISTS `user`; 
  51. CREATE TABLE IF NOT EXISTS `user` ( 
  52.   `namevarchar(10) NOT NULL COMMENT '管理员用户名'
  53.   `passwd` char(32) NOT NULL COMMENT '登录密码MD5值' 
  54. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表'
  55.  
  56. -- 
  57. -- 转存表中的数据 `user` 
  58. -- 
  59.  
  60. INSERT INTO `user` (`name`, `passwd`) VALUES 
  61. ('ttxi''700469ca1555900b18c641bf7b0a1fa1'), 
  62. ('jitttanwa''adac5659956d68bcbc6f40aa5cd00d5c'); 
  63.  
  64. -- 
  65. -- 限制导出的表 
  66. -- 
  67.  
  68. -- 
  69. -- 限制表 `ip_votes` 
  70. -- 
  71. ALTER TABLE `ip_votes` 
  72.   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操作数据库,我它简单的封装一下,代码如下:

  1. /** 
  2.  * 操作数据库 
  3.  * 封装PDO,使其方便自己的操作 
  4.  */ 
  5. class OperatorDB 
  6.     //连接数据库的基本信息 
  7.     private $dbms='mysql';       //数据库类型,对于开发者来说,使用不同的数据库,只要改这个. 
  8.     private $host='localhost';       //数据库主机名 
  9.     private $dbName='voting';     //使用的数据库 
  10.     private $user='voting';       //数据库连接用户名 
  11.     private $passwd='voting';     //对应的密码 
  12.     private $pdo=null; 
  13.  
  14.     public function  __construct() 
  15.     { 
  16.         //dl("php_pdo.dll"); 
  17.         //dl("php_pdo_mysql.dll"); 
  18.         $this->dsn="$this->dbms:host=$this->host;dbname=$this->dbName"
  19.         try 
  20.         { 
  21.             $this->conn=new PDO($this->dsn,$this->user,$this->passwd);//初始化一个PDO对象,就是创建了数据库连接对象$db 
  22.         } 
  23.         catch(PDOException $e
  24.         { 
  25.             die("<br/>数据库连接失败(creater PDO Error!): ".$e->getMessage()."<br/>"); 
  26.         } 
  27.     } 
  28.     public function __destruct() 
  29.     { 
  30.         $this->pdo = null; 
  31.     } 
  32.     public function exec($sql
  33.     { 
  34.     } 
  35.     public function query($sql
  36.     { 
  37.     } 

把连接数据库的信息封装进去方便后续的操作,代码如下:

  1. <?php 
  2. require_once 'OperatorDB.php'
  3. class OperatorVotingDB 
  4.     private $odb
  5.  
  6.     public function  __construct() 
  7.     { 
  8.         $this->odb = new OperatorDB(); 
  9.     } 
  10.     public function __destruct() 
  11.     { 
  12.         $this->odb = null; 
  13.     } 
  14.  
  15.     /** 
  16.      * 清空Voting数据中的所有表 
  17.      * 
  18.      * 调用数据库操作类,执行clear数据库的操作 
  19.      */ 
  20.     public function clearTables() 
  21.     { 
  22.         $sqls = array("TRUNCATE ip_votes;","TRUNCATE count_voting;"); 
  23.         $this->odb->exec($sqls[0]); 
  24.         $this->odb->exec($sqls[1]); 
  25.     } 
  26.  
  27.     /** 
  28.      * 重置count_voting表中的CountValues字段为0 
  29.      * 
  30.      */ 
  31.     public function resetCountValues() 
  32.     { 
  33.         $sql = "UPDATE count_voting SET CountVotes = 0;"
  34.         $this->odb->exec($sql); 
  35.     } 
  36.  
  37.     /** 
  38.      * 投票 
  39.      * 将信息写入ip_votes表 
  40.      * @param type $ip 
  41.      * @param type $loc 
  42.      * @param type $time 
  43.      * @param type $name 
  44.      */ 
  45.     public function vote($ip,$loc,$name
  46.     { 
  47.         $sql = "INSERT INTO ip_votes VALUES (NULL, '$ip', '$loc', NOW(), '$name')"
  48.         $subsql = "SELECT MAX(to_days(VoteTime)) FROM ip_votes WHERE IP='$ip'"
  49.         $stm = $this->odb->query($subsql); 
  50.         if (count($row=$stm->fetchAll())==1) 
  51.         { 
  52.             $now = date("Y-m-d H:i:s"); 
  53.             $subsql = "SELECT to_days('$now');"
  54.             $stm = $this->odb->query($subsql)->fetch(); 
  55.             $time = $stm[0];//使用mysql计算出的today时间 
  56. //            echo $time."<br>"; 
  57. //            echo $row[0][0]; 
  58.             if ($time-$row[0][0]<1)//表中最大的时间和现在的时间$time比较 
  59.             { 
  60.                 echo "投票失败,相同ip需要隔一天才能投票"
  61.                 return
  62.             } 
  63.         } 
  64. //        echo $sql; 
  65.         echo "投票成功!"
  66.         $this->odb->exec($sql); 
  67.     } 
  68.  
  69.     /** 
  70.      * 添加SelectName字段的行 
  71.      * 
  72.      * @param string $name 
  73.      * @param string $label 
  74.      * @param int $count 
  75.      */ 
  76.     public function addSelectName($name$label$count=0) 
  77.     { 
  78.         $sql = "INSERT INTO count_voting VALUES ('$name', '$label', $count);"
  79.         $this->odb->exec($sql); 
  80.     } 
  81.  
  82.     /** 
  83.      * 获取总投票情况,按票数排序的结果 
  84.      * 
  85.      * 按CountVotes字段排序,返回count_voting表 
  86.      * 
  87.      * @param int $n 
  88.      * 
  89.      */ 
  90.     public function getVotesSortByCount($n=-1) 
  91.     { 
  92.         $sql = "SELECT * FROM count_voting ORDER BY CountVotes DESC LIMIT 0 , $n;"
  93.         if (-1 == $n
  94.         { 
  95.             $sql = "SELECT * FROM count_voting ORDER BY CountVotes DESC;"
  96.         } 
  97. //        echo $sql; 
  98.         return $this->odb->query($sql); 
  99.     } 
  100.  
  101.     /** 
  102.      * 获取投票情况,按票数排序并按标签分组的结果 
  103.      * 
  104.      * 按CountVotes字段排序并按LabelName字段分组,返回count_voting表 
  105.      */ 
  106.     public function getVotesGroupByLabel() 
  107.     { 
  108.         $sql = "SELECT * FROM count_voting ORDER BY LabelName DESC;";//开源代码phpfensi.com 
  109. //        echo $sql; 
  110.         return $this->odb->query($sql); 
  111.     } 
  112. ?> 

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

  1. <?php 
  2. /** 
  3.  * 页面跳转函数 
  4.  * 使用js实现 
  5.  * @param string $url 
  6.  */ 
  7. function goToPgae($url
  8.     echo "<script language='javascript' type='text/javascript'>"
  9.     echo "window.location.href='$url'"
  10.     echo "</script>"
  11. function jsFunc($fun$arg=null) 
  12.     echo "<script language='javascript' type='text/javascript'>"
  13.     echo $fun."('$arg');"
  14.     echo "</script>"
  15. function jsFunc3($fun$arg1=null,$arg2=null,$arg3=null) 
  16.     echo "<script language='javascript' type='text/javascript'>"
  17.     echo $fun."('$arg1','$arg2','$arg3');"
  18.     echo "</script>"
  19.     //echo $fun."('$arg1','$arg2','$arg3');"; 
  20.  
  21. function isLoginNow() 
  22.     if ($_COOKIE["user"]==''
  23.     { 
  24.         return false; 
  25.     } 
  26.     return true; 
  27.  
  28. function getClientIP() 
  29.     if ($_SERVER["HTTP_X_FORWARDED_FOR"]) 
  30.     { 
  31.         if ($_SERVER["HTTP_CLIENT_IP"]) 
  32.         { 
  33.                 $proxy = $_SERVER["HTTP_CLIENT_IP"]; 
  34.         } 
  35.         else 
  36.         { 
  37.             $proxy = $_SERVER["REMOTE_ADDR"]; 
  38.         } 
  39.         $ip = $_SERVER["HTTP_X_FORWARDED_FOR"]; 
  40.     } 
  41.     else 
  42.     { 
  43.         if ($_SERVER["HTTP_CLIENT_IP"]) 
  44.         { 
  45.                 $ip = $_SERVER["HTTP_CLIENT_IP"]; 
  46.         } 
  47.         else 
  48.         { 
  49.             $ip = $_SERVER["REMOTE_ADDR"]; 
  50.         } 
  51.     } 
  52.     return $ip
  53.  
  54. //从123查获取ip 
  55. function getIpfrom123cha($ip) { 
  56.     $url = 'http://www.123cha.com/ip/?q='.$ip
  57.         $content = file_get_contents($url); 
  58.         $preg = '/(?<=本站主数据:</li><li style="width:450px;">)(.*)(?=</li>)/isU'
  59.         preg_match_all($preg$content$mb); 
  60.         $str = strip_tags($mb[0][0]); 
  61.         //$str = str_replace(' ', '', $str); 
  62.         $address = $str
  63.         if($address == '') { 
  64.             $address = '未明'
  65.         } 
  66.     return $address
  67.  
  68. //从百度获取ip所在地 
  69. function getIpfromBaidu($ip) { 
  70.     $url = 'http://www.baidu.com/s?wd='.$ip
  71.     $content = file_get_contents($url); 
  72.     $preg = '/(?<=<p class="op_ip_detail">)(.*)(?=</p>)/isU'
  73.     preg_match_all($preg$content$mb); 
  74.     $str = strip_tags($mb[0][1]); 
  75.     $str = str_replace(' '''$str); 
  76.     $address = substr($str, 7); 
  77.     if($address == '') { 
  78.         $address = '未明'
  79.     } 
  80.     return $address
  81. ?> 

然后就是后台管理员的操作怎么弄了,主要是添加投票项的功能,操作数据库上面已经实现,后面的基本上是页面怎么设置,关系到js,添加投票项的页面是动态的,代码如下:

  1. function addVote() 
  2.     right.innerHTML="<h2>添加投票项</h2>"
  3.     right.innerHTML+="<label>投票项标签<label>"
  4.     addInput("right","cLabelName","地区名"); 
  5.     right.innerHTML+="<br><label>投票项名称<label>"
  6.     addInput("right","cSelectName","学校名"); 
  7.     right.innerHTML+="<br>"
  8.     var args = ''./add.php','cSelectName','cLabelName''
  9.     var str = '<input type=button value="u6dfb加" onclick="goToPage('+args+');"/>'
  10.     right.innerHTML+=str; 
  11.  
  12. //添加文本框 
  13. function addInput(parent,id,pla) 
  14.     //创建input 
  15.     var input = document.createElement("input"); 
  16.     input.type = "text"
  17.     input.id = id; 
  18.     input.placeholder = pla; 
  19.     document.getElementById(parent).appendChild(input); 

添加投票项是通过url传递变量到add.php页面的,代码如下:

  1. <?php 
  2.     require_once '../api/func.php'
  3.  
  4.     if (!isLoginNow()) 
  5.     { 
  6.         goToPgae("./index.php"); 
  7.     } 
  8.  
  9.     $name = $_GET["cSelectName"]; 
  10.     $label = $_GET["cLabelName"]; 
  11.     //echo $name."<br>".$label; 
  12.     require_once '../api/OperatorVotingDB.php'
  13.     $ovdb=new OperatorVotingDB(); 
  14.     $ovdb->addSelectName($name,$label); 
  15.     require './header.htm'
  16.     goToPgae("./admin.php?page=add&auto="."$label"."&id=cLabelName&foc=cSelectName&msg=添加成功"); 
  17. ?> 

下面是两个跳转页面的函数,js的,上面func.php中的跳转页面函数也是通过js实现的,代码如下:

  1. //js 
  2. function goToPage(url,arg1,arg2) 
  3.     var a = document.getElementById(arg1).value; 
  4.     var b = document.getElementById(arg2).value; 
  5.     url += '?'+arg1+'='+a; 
  6.     url += '&'+arg2+'='+b; 
  7.     window.location.href=url; 
  8.  
  9. function goToPage1(url) 
  10.     window.location.href=url; 

还有修改删除功能没有实现,我应该不会去实现那个了吧,js的话和添加功能差不多.

登录模块的话网上很多,模仿的,就是提交表单,查找数据库,返回结果,成功则设置cookie,后台的每个页面都添加了检测cookie的功能的.

Tags: php投票系统 php投票源码

分享到: