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脚本如下,代码如下:
- --
- -- 表的结构 `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 'OperatorDB.php';
- 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, '$ip', '$loc', NOW(), '$name')";
- $subsql = "SELECT MAX(to_days(VoteTime)) FROM ip_votes WHERE IP='$ip'";
- $stm = $this->odb->query($subsql);
- if (count($row=$stm->fetchAll())==1)
- {
- $now = date("Y-m-d H:i:s");
- $subsql = "SELECT to_days('$now');";
- $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 ('$name', '$label', $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;";//开源代码phpfensi.com
- // echo $sql;
- return $this->odb->query($sql);
- }
- }
- ?>
下面还有需要的函数,代码如下:
- <?php
- /**
- * 页面跳转函数
- * 使用js实现
- * @param string $url
- */
- function goToPgae($url)
- {
- echo "<script language='javascript' type='text/javascript'>";
- echo "window.location.href='$url'";
- echo "</script>";
- }
- function jsFunc($fun, $arg=null)
- {
- echo "<script language='javascript' type='text/javascript'>";
- echo $fun."('$arg');";
- echo "</script>";
- }
- function jsFunc3($fun, $arg1=null,$arg2=null,$arg3=null)
- {
- echo "<script language='javascript' type='text/javascript'>";
- echo $fun."('$arg1','$arg2','$arg3');";
- echo "</script>";
- //echo $fun."('$arg1','$arg2','$arg3');";
- }
- function isLoginNow()
- {
- if ($_COOKIE["user"]=='')
- {
- 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 = 'http://www.123cha.com/ip/?q='.$ip;
- $content = file_get_contents($url);
- $preg = '/(?<=本站主数据:</li><li style="width:450px;">)(.*)(?=</li>)/isU';
- preg_match_all($preg, $content, $mb);
- $str = strip_tags($mb[0][0]);
- //$str = str_replace(' ', '', $str);
- $address = $str;
- if($address == '') {
- $address = '未明';
- }
- return $address;
- }
- //从百度获取ip所在地
- function getIpfromBaidu($ip) {
- $url = 'http://www.baidu.com/s?wd='.$ip;
- $content = file_get_contents($url);
- $preg = '/(?<=<p class="op_ip_detail">)(.*)(?=</p>)/isU';
- preg_match_all($preg, $content, $mb);
- $str = strip_tags($mb[0][1]);
- $str = str_replace(' ', '', $str);
- $address = substr($str, 7);
- if($address == '') {
- $address = '未明';
- }
- 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 = ''./add.php','cSelectName','cLabelName'';
- var str = '<input type=button value="u6dfb加" onclick="goToPage('+args+');"/>';
- 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);
- }
添加投票项是通过url传递变量到add.php页面的,代码如下:
- <?php
- require_once '../api/func.php';
- if (!isLoginNow())
- {
- goToPgae("./index.php");
- }
- $name = $_GET["cSelectName"];
- $label = $_GET["cLabelName"];
- //echo $name."<br>".$label;
- require_once '../api/OperatorVotingDB.php';
- $ovdb=new OperatorVotingDB();
- $ovdb->addSelectName($name,$label);
- require './header.htm';
- 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 += '?'+arg1+'='+a;
- url += '&'+arg2+'='+b;
- window.location.href=url;
- }
- function goToPage1(url)
- {
- window.location.href=url;
- }
还有修改删除功能没有实现,我应该不会去实现那个了吧,js的话和添加功能差不多.
登录模块的话网上很多,模仿的,就是提交表单,查找数据库,返回结果,成功则设置cookie,后台的每个页面都添加了检测cookie的功能的.
Tags: php投票系统 php投票源码
- 上一篇:php 在线解压程序
- 下一篇:php ajax 留言板
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)