在这个数字化时代,投票系统已经成为网站互动的重要组成部分。无论是音乐网站、新闻门户还是社区论坛,用户投票都是收集用户意见、增加用户参与度的有效方式。然而,传统的投票系统往往依赖数据库存储投票结果,这不仅增加了系统的复杂性,还可能导致数据安全问题。本文将介绍一种基于PHP和DOMDocument的无数据库投票系统,该系统通过XML文件存储投票结果,并通过IP地址防止重复投票,从而提供了一种简单、安全且高效的投票解决方案。
运营着一个本地音乐网站,每个月都希望会员们能够投票选出他们最喜欢的本地乐队。然而,Joomla的默认投票应用会在cookie中记录IP地址,这意味着用户只需删除cookie就可以再次投票,这种不公平的系统使得投票结果容易被操纵。因此,开始在网上寻找第三方组件,希望能够记录IP地址并确保用户每天只能投票一次。
经过一番搜索,发现现有的解决方案要么速度极慢,要么需要电子邮件注册(意味着加入垃圾邮件列表),或者带有各种弹出广告。无奈之下,决定重拾PHP技能,自己编写投票系统。虽然更擅长ASP.NET和C#,但对PHP也有一定的了解。因此,在阅读本文时,请记住并非PHP领域的专家。
幸运的是,运行这个投票系统只需要PHP 5.0。这是因为DOMDocument对象是PHP 5的新特性。不需要任何数据库系统,因为这个投票系统使用简单的文件I/O和XML。
如果想要跳过教程,以下是快速安装指南。如果想知道程序的详细工作原理,请继续阅读!
就是这样!请注意,addresses.xml文件中至少应该有1个地址条目(127.0.0.1的回环地址即可)。
PHP投票系统非常简单,它包含4个PHP文件、2个XML文件和一个样式表。从技术上讲,用户只会看到其中的两个页面,它们如下所示:
loadpoll.php负责显示投票。它的工作原理非常简单:
$doc = new DOMDocument();
$doc->load("xml/results.xml");
$root = $doc->getElementsByTagName("results")->item(0);
$question = $root->getAttribute("question");
$pollitems = $doc->getElementsByTagName("pollitem");
foreach ($pollitems as $pollitem) {
// 创建一个单选按钮...
}
基本上只是使用DOMDocument对象提供的方法来遍历节点,然后输出一些HTML以适应单选按钮控件。最后一步是在单选按钮的onclick事件上设置一段JavaScript。这样做的目的是将隐藏输入字段的文本填充为投票的值。这样,可以有一个简单的JavaScript confirm()对话框来确保设置了值。如果没有设置,就不会提交投票。一旦设置了该值并点击“投票”,表单(action="savevote.php")将隐藏值发布到savevote.php。以下是JavaScript函数:
function setVote(voteName) {
document.getElementById("votefor").value = voteName;
}
function confirmSubmit() {
if (document.getElementById("votefor").value == "") {
var agree = confirm("请在投票前选择一个条目。");
return false;
}
}
savevote.php是最大的文件,也是工作量最大的文件。操作顺序如下:
显示结果可以很简单,一个带有“条目:xx票”的单行项目就足够了。但是,想变得更聪明。喜欢显示一个折线图,折线图内显示投票百分比的想法。现在,不必这样做,但如果对如何做到这一点感兴趣,请继续阅读。
首先,需要图表的总票数。在代码中,这样获取它:
// 获取最大投票计数
$doc = new DOMDocument();
$doc->load("xml/results.xml");
$maxvotes = 0;
$pollitems = $doc->getElementsByTagName("pollitem");
foreach ($pollitems as $pollitem) {
$votes = $pollitem->getElementsByTagName("votes");
$vote = $votes->item(0)->nodeValue;
$maxvotes = $maxvotes + $vote;
}
现在已经得到了最大值,将重新遍历results.xml文件以计算百分比。
// 生成结果表
$doc = new DOMDocument();
$doc->load("xml/results.xml");
$pollitems = $doc->getElementsByTagName("pollitem");
foreach ($pollitems as $pollitem) {
$entries = $pollitem->getElementsByTagName("entryname");
$entry = $entries->item(0)->nodeValue;
$votes = $pollitem->getElementsByTagName("votes");
$vote = $votes->item(0)->nodeValue;
$tempWidth = $vote / $maxvotes;
$tempWidth = 300 * $tempWidth;
$votepct = round(($vote / $maxvotes) * 100);
echo "$entry ";
echo "($vote votes) ";
}
所做的就是创建一个包含三列的表格。第一列将包含条目名称,第二列将有折线图和百分比,最后一列将包含总票数。
创建图表的方法是为每个条目创建一个DIV对象。基础是DIV的最大宽度将是300px。可以将其设置为任何喜欢的值,只要确保它适合表格和页面!所以,要得到DIV的宽度,只需要取票数($vote),除以最大票数($maxvote),然后将该百分比值乘以300。假设有30票,总共100票,30/100 = 0.3,0.3 * 300 = 90,DIV需要90像素宽。然后,要得到百分比(放在DIV中间),只需要取$vote/$maxvote,四舍五入值,然后乘以100。使用上述示例,这将给30%。
现在,当创建每个DIV时,知道要制作每个DIV的宽度,以及要放在DIV中间的%值。认为为每个div创建不同的颜色会很酷,所以写了一个getRandomColor()函数,并将DIV的background-color样式设置为该函数返回的任何值。
// 返回一个随机的RGB颜色(用于给投票条上色)
function getRandomColor() {
$r = rand(128, 255);
$g = rand(128, 255);
$b = rand(128, 255);
$color = dechex($r) . dechex($g) . dechex($b);
echo "$color";
}