投票很有趣!它们可以帮助吸引您网站的读者,并为您和投票者提供有价值的信息。让我们一起从头开始构建一个投票。从 Photoshop 设计到为其提供支持的 PHP/MySQL,我们将逐步完成所有步骤。以下是我们将构建的内容

实时演示已不再在线,但您可以 下载此演示的所有文件的 .zip 文件。
1. 在 Photoshop 中设计背景
创建一个全新的 Photoshop 文档。在我的文档中,我已将背景填充为深蓝色(#233743),并将其大小设置为 700x700px。

然后在背景图层之上创建一个全新的图层(按图层调色板中的小页面图标)。选择渐变工具(油漆桶工具的子工具)。确保渐变工具设置为“前景色到透明”、“径向”和“完全不透明”,如下所示
在我的文档中,我使用了稍浅的蓝色(#364c5a),并从顶部中间附近拖出一个渐变。渐变可以“超出”顶部,但请确保它不会超出任一侧或底部。这里的想法是,我们将将其居中在一个匹配蓝色的背景上,因此我们不希望渐变突然结束。我们将其单独放在一个图层上的原因是,我们可以调整它而无需重新进行操作。

现在让我们在顶部添加有趣的“投票!”文本。在这里,我使用了 Agenda Black 字体(我的新宠之一),颜色为更浅的蓝色(#e3f1fa)。我对其进行了自由变换(Command-T)以使其稍微旋转,然后在图层样式中为其添加了轻微的投影。

现在图形已准备好保存。您可以从文件菜单中“存储为 Web 所用格式和设备”。使用高质量 JPG 设置(最适合具有渐变的大型图像)。将文件命名为“page-bg.jpg”,并将其保存到您将用于此项目的目录内的“images”文件夹中。

2. 构建页面结构
在我们的案例中,投票只是一个非常简单的表单。基本上是一系列单选按钮输入和一个提交按钮。以下是整个 HTML 标记的外观
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Poll</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<fieldset>
<legend>What is your JavaScript library of choice?</legend>
<form action="<?php echo $editFormAction; ?>" id="form1" name="form1" method="POST">
<label>
<input type="radio" name="Poll" value="mootools" id="Poll_0" />
Mootools
</label>
<label>
<input type="radio" name="Poll" value="prototype" id="Poll_1" />
Prototype
</label>
<label>
<input type="radio" name="Poll" value="jquery" id="Poll_2" />
jQuery
</label>
<label>
<input type="radio" name="Poll" value="spry" id="Poll_3" />
Spry
</label>
<label>
<input type="radio" name="Poll" value="other" id="Poll_4" />
Other
</label>
<input type="submit" name="submit" id="submit" value="Vote" />
<input type="hidden" name="id" value="form1" />
<input type="hidden" name="MM_insert" value="form1" />
</form>
</fieldset>
</body>
</html>
这里需要注意的几点。我将表单放在了一个 fieldset 中。这里没有功能相关的内容,我只是喜欢 fieldset/legend 组合的外观,并且它为我们提供了一些 CSS 样式的挂钩。还要注意输入是如何位于 label 元素内的。这允许用户单击文字以及单选按钮来选择它,这很好。还要注意表单操作中的 PHP 代码片段,我们稍后会讲到。
以下是 CSS
* {
margin: 0;
padding: 0;
}
body {
font-size: 62.5%;
font-family: Georgia, serif;
background: url(images/page-bg.jpg) top center no-repeat #233743;
}
h6 {
font-size: 1.4em;
margin-bottom: 15px;
}
a { color: white; }
label, li {
display: block;
padding: 5px;
font-size: 1.4em;
color: #e3f1fa;
}
fieldset {
margin: 115px auto;
width: 400px;
padding: 8px 15px 15px 15px;
border: 1px solid white;
display: block; /* IE 7 Requires This */
}
legend {
padding: 4px 6px 4px 6px;
border: 1px solid white;
font-size: 2.0em;
color: #e3f1fa;
font-style: italic;
}
ul { list-style: none; margin-bottom: 15px;}
.results-bar {
padding: 10px;
color: white;
background: url(images/result-bar-bg.png) left center;
white-space: nowrap;
}
span.total-votes {
font-size: 2.6em;
}
请注意底部针对我们标记中尚未包含的内容的样式,这些样式是针对我们稍后将要介绍的结果页面。
3. 创建一个数据库来存储结果
大多数托管套餐允许您在服务器上创建数据库。如果您还不知道如何操作,可能需要联系他们或搜索其帮助区域以了解如何添加新数据库。
CSS-Tricks 位于 Media Temple,因此域管理员区域中有一个方便的小工具可用于创建新数据库

确保这是一个 MySQL 数据库。您需要了解的四件事是主机名、数据库用户名、数据库“密码”和数据库名称。
现在,您需要在为此项目启动的目录中创建一个名为“conn_vote.php”的新文件。我已将其放在名为“Connections”的子文件夹中。以下是 PHP
<?php
# FileName="Connection_php_mysql.htm"
# Type="MYSQL"
# HTTP="true"
$hostname_conn_vote = "localhost";
$database_conn_vote = "your-database-name";
$username_conn_vote = "your-database-username";
$password_conn_vote = "your-database-password";
//$conn_vote = mysql_pconnect($hostname_conn_vote, $username_conn_vote, $password_conn_vote) or trigger_error(mysql_error(),E_USER_ERROR);
$conn_vote = mysql_connect($hostname_conn_vote, $username_conn_vote, $password_conn_vote) or die('Can\'t create connection: '.mysql_error());
mysql_select_db($database_conn_vote, $conn_vote) or die('Can\'t access specified db: '.mysql_error());
?>
请注意上面以粗体显示的四行,它们是前面提到的您需要了解的四件事的四个变量。您的主机很可能是 localhost,但并非总是如此。以我为例,在 Media Temple 中,它类似于:internal-db.s12345.gridserver.com
您的全新空数据库将需要一个表结构和一些假数据才能开始使用。以下是一些您可以运行的 SQL 代码来完成此操作
--
-- Table structure for table `poll`
--
CREATE TABLE `poll` (
`id` int(3) NOT NULL auto_increment,
`question` varchar(200) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=43 ;
--
-- Dumping fake data for table `poll`
--
INSERT INTO `poll` VALUES (42, 'jquery');
INSERT INTO `poll` VALUES (41, 'mootools');
INSERT INTO `poll` VALUES (40, 'other');
INSERT INTO `poll` VALUES (39, 'mootools');
INSERT INTO `poll` VALUES (38, 'jquery');
INSERT INTO `poll` VALUES (37, 'mootools');
INSERT INTO `poll` VALUES (36, 'spry');
INSERT INTO `poll` VALUES (35, 'jquery');
INSERT INTO `poll` VALUES (21, 'mootools');
INSERT INTO `poll` VALUES (22, 'other');
INSERT INTO `poll` VALUES (23, 'mootools');
INSERT INTO `poll` VALUES (24, 'mootools');
INSERT INTO `poll` VALUES (25, 'prototype');
INSERT INTO `poll` VALUES (26, 'other');
INSERT INTO `poll` VALUES (27, 'mootools');
INSERT INTO `poll` VALUES (28, 'spry');
INSERT INTO `poll` VALUES (29, 'jquery');
INSERT INTO `poll` VALUES (30, 'mootools');
INSERT INTO `poll` VALUES (31, 'prototype');
INSERT INTO `poll` VALUES (32, 'mootools');
INSERT INTO `poll` VALUES (33, 'mootools');
INSERT INTO `poll` VALUES (34, 'mootools');
大多数主机还允许您访问 phpMyAdmin 来运行此类代码。**请确保**您位于新数据库中,然后您可以粘贴该 SQL 代码并运行它。

4. 使其与 PHP 协同工作
现在,我们已准备好使用一些 PHP 编码技巧来使这一切正常工作。我不能假装理解所有这些,但其要点是,它将获取您选择的选项,将其转换为易读且安全的字符串值,并将其作为新条目保存在数据库中的该表中。
非常感谢 Jonathan Fean 为此提供支持的 PHP 代码,以及 David Walsh 帮助我解决了一些问题并使其在我的服务器上运行。
将此 PHP 代码插入 poll.php 文件的顶部(甚至在 DOCTYPE 之前)
<?php require_once('Connections/conn_vote.php'); ?>
<?php
if (!function_exists("GetSQLValueString")) {
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "")
{
$theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;
$theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue);
switch ($theType) {
case "text":
$theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
break;
case "long":
case "int":
$theValue = ($theValue != "") ? intval($theValue) : "NULL";
break;
case "double":
$theValue = ($theValue != "") ? "'" . doubleval($theValue) . "'" : "NULL";
break;
case "date":
$theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
break;
case "defined":
$theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
break;
}
return $theValue;
}
}
$editFormAction = $_SERVER['PHP_SELF'];
if (isset($_SERVER['QUERY_STRING'])) {
$editFormAction .= "?" . htmlentities($_SERVER['QUERY_STRING']);
}
if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form1")) {
$insertSQL = sprintf("INSERT INTO poll (id, question) VALUES (%s, %s)",
GetSQLValueString($_POST['id'], "int"),
GetSQLValueString($_POST['Poll'], "text"));
mysql_select_db($database_conn_vote, $conn_vote);
$Result1 = mysql_query($insertSQL, $conn_vote) or die(mysql_error());
$insertGoTo = "results.php";
if (isset($_SERVER['QUERY_STRING'])) {
$insertGoTo .= (strpos($insertGoTo, '?')) ? "&" : "?";
$insertGoTo .= $_SERVER['QUERY_STRING'];
}
header(sprintf("Location: %s", $insertGoTo));
}
$colname_rs_vote = "-1";
if (isset($_GET['recordID'])) {
$colname_rs_vote = $_GET['recordID'];
}
mysql_select_db($database_conn_vote, $conn_vote);
$query_rs_vote = sprintf("SELECT * FROM poll WHERE id = %s", GetSQLValueString($colname_rs_vote, "int"));
$rs_vote = mysql_query($query_rs_vote, $conn_vote) or die(mysql_error());
$row_rs_vote = mysql_fetch_assoc($rs_vote);
$totalRows_rs_vote = mysql_num_rows($rs_vote);
?>
以及 poll.php 文件末尾的此 PHP 代码(甚至在 <html> 之后)
<?php
mysql_free_result($rs_vote);
?>
5. 创建结果页面
因此,我们的投票已启动并运行,并成功收集了投票,但结果页面才是真正的回报!这不仅是有趣的部分,而且我们的 PHP 函数在您按下投票按钮后会自动重定向到“results.php”页面,因此我们必须构建一个 =)
这次,我将把所有标记和 PHP 代码一起放在一个大块中提供给您
<?php require_once('Connections/conn_vote.php'); ?>
<?php
if (!function_exists("GetSQLValueString")) {
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "")
{
$theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue;
$theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue);
switch ($theType) {
case "text":
$theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
break;
case "long":
case "int":
$theValue = ($theValue != "") ? intval($theValue) : "NULL";
break;
case "double":
$theValue = ($theValue != "") ? "'" . doubleval($theValue) . "'" : "NULL";
break;
case "date":
$theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
break;
case "defined":
$theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
break;
}
return $theValue;
}
}
mysql_select_db($database_conn_vote, $conn_vote);
$query_rs_vote = "SELECT * FROM poll";
$rs_vote = mysql_query($query_rs_vote, $conn_vote) or die(mysql_error());
$row_rs_vote = mysql_fetch_assoc($rs_vote);
$totalRows_rs_vote = mysql_num_rows($rs_vote);
$resultQuestion1 = mysql_query("SELECT * FROM poll WHERE question='mootools'");
$num_rowsQuestion1 = mysql_num_rows($resultQuestion1);
$resultQuestion2 = mysql_query("SELECT * FROM poll WHERE question='prototype'");
$num_rowsQuestion2 = mysql_num_rows($resultQuestion2);
$resultQuestion3 = mysql_query("SELECT * FROM poll WHERE question='jquery'");
$num_rowsQuestion3 = mysql_num_rows($resultQuestion3);
$resultQuestion4 = mysql_query("SELECT * FROM poll WHERE question='spry'");
$num_rowsQuestion4 = mysql_num_rows($resultQuestion4);
$resultQuestion5 = mysql_query("SELECT * FROM poll WHERE question='other'");
$num_rowsQuestion5 = mysql_num_rows($resultQuestion5);
$percentQuestion1 = ($num_rowsQuestion1 / $totalRows_rs_vote)*100;
$percentQuestion2 = ($num_rowsQuestion2 / $totalRows_rs_vote)*100;
$percentQuestion3 = ($num_rowsQuestion3 / $totalRows_rs_vote)*100;
$percentQuestion4 = ($num_rowsQuestion4 / $totalRows_rs_vote)*100;
$percentQuestion5 = ($num_rowsQuestion5 / $totalRows_rs_vote)*100;
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Results</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<fieldset>
<legend>Results</legend>
<ul>
<li>
<?php echo $num_rowsQuestion1 ?> Mootools
<br />
<div class="results-bar" style="width: <?php echo round($percentQuestion1,2); ?>%;">
<?php echo round($percentQuestion1,2); ?>%
</div>
</li>
<li>
<?php echo $num_rowsQuestion2 ?> Prototype
<div class="results-bar" style="width: <?php echo round($percentQuestion2,2); ?>%;">
<?php echo round($percentQuestion2,2); ?>%
</div>
</li>
<li>
<?php echo $num_rowsQuestion3 ?> jQuery
<div class="results-bar" style="width: <?php echo round($percentQuestion3,2); ?>%;">
<?php echo round($percentQuestion3,2); ?>%
</div>
</li>
<li>
<?php echo $num_rowsQuestion4 ?> Spry
<div class="results-bar" style="width: <?php echo round($percentQuestion4,2); ?>%;">
<?php echo round($percentQuestion4,2); ?>%
</div>
</li>
<li>
<?php echo $num_rowsQuestion5 ?> Other
<div class="results-bar" style="width: <?php echo round($percentQuestion5,2); ?>%;">
<?php echo round($percentQuestion5,2); ?>%
</div>
</li>
</ul>
<h6>Total votes: <?php echo $totalRows_rs_vote ?></h6>
Back to Voting
</fieldset>
</body>
</html>
<?php
mysql_free_result($rs_vote);
?>
请注意,PHP 中进行了一些小的计算,这些计算将计算每个投票选项的总投票百分比。这不仅是有用的信息,而且我们可以使用该百分比来设置条形的宽度,从而为我们的结果添加一些视觉效果。每个投票选项都有自己的列表项,其中显示该项目的总投票数以及“results-bar”,其宽度通过将内联宽度值设置为计算出的百分比来确定。在我们的 CSS 中,我们已经使用细微的图案化背景图像对该 div 进行了样式设置。
实时演示已不再在线,但您可以 下载此演示的所有文件的 .zip 文件。
(请记住:这需要运行 PHP 和 MySQL 数据库的服务器,因此您需要按照上述步骤才能使其在您自己的服务器上运行。包含 Photoshop 文件。)
太棒了。这也可以在只允许一个数据库的用户的主机上使用,只需添加表信息即可,对吧?这是否也适用于多个投票?如果我错过了,我表示歉意。:) 我太喜欢 PHP 了!
您好,
这是否有点过头了?
像这样
“SELECT * FROM poll”… 并且重复了 5 次!!
我认为这样的方法更好
$questions = [‘question1,’question2’, ‘question3’];
mysql_query(‘SELECT poll.field1, poll.field2… FROM poll WHERE poll.question IN (‘.implode(‘, ‘, $questions).’);’);
:)
@Lindsey:当然,如果您愿意,可以将表添加到现有数据库中,我只是不想提倡乱动现有的重要数据库=)。我知道我肯定不会在我的 WordPress 数据库上测试它!
是的,我认为只要答案都不同,这就可以用于多个投票。我没有编写此 PHP 代码,因此我不太熟悉,但看起来答案被存储在表中,就像答案值的字符串一样,而不是像 ID# 这样的唯一值。
出色的作品,我已经为其他网站做过这种投票。
并且我可以说这段代码非常好。
非常专业。
也许,下一步是调用一个 ajax 函数在同一页面上显示它(result.php),这非常容易…
干得好。
再见,Laurent。
这是一个很好的开始,我喜欢它的样式(即显示和执行方式的简洁性)。对我来说,下一步将是将数据与源代码分离。我宁愿看到投票答案/问题来自数据库,并在数据库中维护一个投票计数字段。目前,每次投票都会向数据库中添加一个新条目,因此如果投票数为 10,000,数据库表中最终可能会出现 10,000 个条目或行。
另一方面,这很简单,这很好。感谢您提供此功能。
@Laurent:使用AJAX加载结果页面的想法很好。我想我会研究一下,如果成功了会发布一些内容。
@Donna:你说得对,对于像这样的简单投票,最好在数据库中存储和累加总数,而不是存储每个投票记录。但是,通过这种方式,你可以添加“姓名”或“电子邮件”等信息,这样投票也可以为你收集信息。然后你可能需要单独存储每个条目……
Chris说得对。你说的没错,在投票中收集其他信息可能会很有用。
再次感谢你在这个很棒的网站上付出的所有努力。这是我最喜欢的每天都会查看的网站——我总是能学到一些新的和有用的东西!
哇,Chris,很棒的文章!你非常出色地解释了数据库和PHP,使它变得非常容易理解。谢谢!
这是一个非常棒的教程,因为它涵盖了很多方面。不过我有一个问题,如果你想让它“可编辑”怎么办?例如,你想让人们创建自己的投票。是否有为此添加的editPoll脚本/php页面?我之所以这么问是因为投票很好,但当其他人只需点击并输入变量并提交给所有人时,它们的效果会更好。
我对PHP/编码以及类似的东西(在与癌症作斗争的同时学习)真的是超级新手,所以如果我的问题很蠢,我表示歉意。我只是在努力弄清楚一些事情,以便如果我的健康状况真的很快恶化,我可以为我的朋友留下一些东西。
感谢任何帮助或指导——再次感谢你的教程——它非常棒,我觉得我学到了很多东西 :)
-Chez
再次问好
所以,嗯……在滚动浏览时,我意识到我错过了Donna的一些非常有见地的评论。我同意她的观点,她说“我宁愿看到投票答案/问题来自数据库,并在数据库中维护一个投票计数字段。按照目前的方式,每次投票都会在数据库中添加一个新条目,因此如果投票数为10,000次,数据库表中最终可能会出现10,000个条目或行。”
虽然对于像我这样的人来说,如果我能获得20票,我会很高兴,而且我认为大多数部署的投票都是这样运作的——雅虎群组提供投票,许多其他论坛也是如此,我认为如果将它们考虑在内,它们的愚蠢投票(就像我的投票一样愚蠢,所以我这样说并不是在贬低它们)。我喜欢数据库包含所有内容并管理数据的想法——我也喜欢它为你收集信息(如IP地址)的想法,以便某人只能投票一次,这样信息就不会被扭曲。此外,收集电子邮件和其他信息也很酷。
有什么想法、提示或建议吗?
这也是我偶然发现的每日博客吗?
感谢你提供的很棒的投票示例!
拥抱
-Chez
首先,我不知道这段代码是否可以使用,因为我对PHP没有能力。
其次,我将在自己的网站上测试它,以获取有关特定主题的更多信息。
感谢你的工作。
Ralph
谢谢,你帮了我很大的忙,现在我的投票看起来更好了。
很酷的教程……如何增强功能以防止投票者多次投票?再次感谢!
非常棒的教程。我希望下周能完成一些东西。感谢Chris发布这篇帖子,以便像我这样的人能够理解它。
有没有办法防止人们在这些投票中多次投票。
“CREATE TABLE
poll
(id
int( 3 ) NOT NULL AUTO_INCREMENT ,question
varchar( 200 ) default NULL ,PRIMARY KEY (
id
)) TYPE : MYISAM AUTO_INCREMENT :43;
MySQL表示:文档
#1064 – 您的SQL语法存在错误;请查阅与您的MySQL服务器版本相对应的参考手册,以获取正确的语法。在第5行附近“TYPE:MyISAM AUTO_INCREMENT:43”处使用。
请帮我解决这个问题……
一位读者最近告诉我将最后一行更新为
嗨,这里有一个不错的投票:D
但我想创建类似这样的东西
“用户应该登录(应该使用会话),然后选择候选人的投票,然后注销,另一个用户再次登录,依此类推。”
用户 -> 登录 -> 投票 -> 注销 -> 依此类推。
你能帮我提供教程吗? :)