Web 投票或 Web 表决为从网站访问者那里获得反馈提供了一种很好的方式。本文展示了如何使用 IBM® DB2® Universal Database™(UDB)、Hypertext Preprocessor (PHP) 和 Linux™ 将这项功能添加到 Web 站点中。您将研究的设计包括:使用数据库存储选票信息,使用 PHP 脚本语言实现投票,以及创建、管理和审查选票。 为什么要进行 Web 投票? 从访问者那里取得反馈 Web 投票或 Web 表决为从网站访问者那里获得反馈提供了一种很好的方式。本文将解释如何将这项功能添加到 Web 站点中。首先,您将看到关于如何进行有意义投票的设计方面的某些细节,之后再进入技术细节。您将研究的设计包括:使用数据库存储选票信息,使用 PHP 脚本语言实现投票,以及创建、管理和审查选票。将这项功能添加到 Web 站点非常简单。请注意,这里给出的代码是由一个 12 岁的孩子创建的。 示例投票 如果使用过 Web 浏览器,那么您可能已经见过 Web 投票这种形式,甚至还自己投过票。图 1 中便是一个 Web 投票的例子。在下一节中,您将研究该选票可能有质量问题的地方。这种选票会有“引导选民”的嫌疑。
图 1. 一种示例选票
![]()
有很多方式可以实现 Web 投票,可以通过一个数据库来实现,或者只需发送 e-mail 给投票管理员就可以实现。投票活动越是活跃,数据库也就变得越是重要,通过数据库技术可以管理事务工作负载、投票结果以及产生报告。 小慌、谎言、统计及选票 统计常常受到责难,但它的确能提供对投票数据的深刻洞察。您所进行的投票有多大的有效性呢?这取决于问题和应答的措辞,还有您想从投票中得到什么样的结 论。有些时候荒谬的投票错误也会成为报纸的头条。 由于这是一篇关于计算机的文章,而不是关于统计学的文章,因此本文只是一个缩减版的投票统计实验设计。请遵从下面的一组指导方针,尽量获得对网站访问者想 法的理解。如果您试图使用投票来达到个人的目的,那么可能与这里的建议背道而驰了。图 1 中的选票只是选票问答设计的一个模仿品。 提供不包含判定性形容词的中立问题。 提供包含多种选择的答案范围。 包括一个“以上都不是”的选项,或投票者自己填写非指定的答案。 尽量取得目标群体的随机抽样。 即使有大量的人参与了投票,也不要假定得到的结果是有效的。 即使只有少数人参与了投票,也不要假定得到的结果是无效的。 记住,投票活动只是对以下人的抽样: 在大多数情况下,大量的抽样可以提供可靠的结果。如果抽样较小,只要目标人口数不大,投票可能仍然是有效的。例如,如果您要对 1904 年 1 月 1 日出生的所有双胞胎进行一次投票,由于目前存活的目标人口规模已经很小,因此,如果参与投票的人很少,那么他可能代表存活的目标人口的 50% 甚至 100%。 即使有很多人响应,也未必能得到有效的结果。如果投票活动是政治性或宗教性的,那么网站可能会陷入问题双方激进组织的较量当中。这样一来,由于无法获得随 机的抽样,投票只能反映各激进组织的组织技巧和精力。 投票系统的架构 图 2 中说明了浏览器、Web 服务器和数据库服务器。在本文中,所有组件都运行在 Red Hat Enterprise Server v3 上。以下列出了用于 DB2 的受支持的 Linux 发行版:
http://www-306.ibm.com/software/data/db2/linux/validate 您也可以选择在 Win32 上实现 Web 投票。
图 2. 浏览器、Web 服务器和数据库简图
![]()
实现 Web 投票的步骤概述 1. 收集各组件 您将需要 Apache、PHP 和 DB2 for Linux。Web 投票也可以在其他平台上实现,但是这里不作论述。 2. 安装和配置各组件 存在着很多这方面的文档。但是,本文只是特别谈到本系统所特有的文档。 3. 安装和配置源代码 要做到这一点,需要下载源代码 zip 文件 pollsource.zip。 然后,需要将这些文件解压到 Apache "DocumentRoot" 所对应的文件夹中。默认情况下,该文件夹位于 Red Hat Linux 系统上,DocumentRoot 是 /var/www/html/ 。 4. 存储选票数据 创建表和关系来存储选票信息。然后使用 SQL insert 语句创建一个简单的选票。此后创建的选票维护 PHP 屏幕是添加和维护选票的主要方式,您无需编写很多的 SQL 便可以使网站运行。 组件 本项目的三个关键部分是 Apache Web Server、PHP 编程环境和 DB2 服务器。关于如何安装和配置这些组件的文档已经有很多,因此在本文中,您将重点关注安装本环境时所特有的一些方面。关于安装和配置参考的链接,将在后面讨 论。 Apache Web Server www.apache.org 上提供了 Apache。Linux 发行版可能包括一个 Apache 环境。您将需要 apache/bin/apxs二进制文件来构建 PHP 环境。如果系统中没有安装该二进制文件,那么可以从 rpm安装,或者从源代码构建 Apache。 PHP www.PHP.net上提供了 PHP。linux 发行版可能已经包含 PHP 环境。不过,为了一起使用 DB2 和 PHP,必须重新编译 PHP,以包括 Open Database Connectivity (ODBC) 支持。您可以在以下链接中找到关于如何完成这些操作的说明:
http://www.ibm.com/developerworks/cn/db2/library/techarticles/scott/0614_scott.html。 DB2 UDB DB2 Quick Beginnings 说明了安装和配置的各个步骤。为了验证安装和 ODBC 连接,需要进入 sample/cli 目录 ,并使用 bldapp脚本构建 dbinfo 样本。在使 DB2 运行之后,便可以将 PHP 连接到数据库。 连接各组件 下面是一篇关于如何连接 Apache、PHP 和 DB2 的好文章:
http://www.ibm.com/developerworks/cn/dmdd/library/techarticles/scott/0614_scott.shtml。 设置数据库以便使用它 出于安全方面的原因,不要以管理员的身份连接到数据库。而是要暂时以 db2inst1的身份登录。完成登录之后,请运行下面三个命令: db2 => create database phpweb
db2 => connect to phpweb
db2 => grant dbadm on database to phpweb 现在,就可以退出 db2inst1了。 存储 poll 数据 您将把投票问题和结果放入到一个数据库中,比如 DB2 中。将重要信息归入一个数据库中。这样做是为了便于访问、更新、备份、历史访问和管理。为了存储与投票相关的信息,还需要一个数据库模式。下面是所使用的 表: -表名: polls
"polls" 表中的列是:
pollkey —— 票号,这是主键。
question —— 投票问题的文本,放在一个 varchar 字段中。
pollstartdate —— 投票起始日期。
pollenddate —— 指定的投票截止日期。
表名: pollresponses
"pollresponses" 表中的列是:
responsekey —— 作为应答的惟一标识符,是主键。
pollkey —— 对 "polls" 表的引用,以便将应答指派给一个投票问题。
responsenum —— 用于排列对某一特定问题的应答的编号。
responsetext —— 应答的文本。
votes —— 同意此应答的票数。
|
要创建这些表,可以使用以下 SQL:
清单 1. 用来存储投票问题和应答的模式
CONNECT TO PHPWEB;
CREATE TABLE polls (
pollkey int primary key,
question varchar(500),
pollstartdate date,
pollenddate date
);
CREATE TABLE pollresponses (
responsekey int primary key,
pollkey int references polls,
responsenum int,
responsetext varchar(300),
votes int
);
-- create an index on the pollresponse pollkey column
-- since most joins use this to join to the polls table
create index i_response on pollresponses ( pollkey );
--Example of creating a new poll
INSERT INTO polls VALUES
(1, 'What do you think of this perfect article?', '2004-05-30','2005-01-01');
--The number 1 is the number of the poll, which is the primary key
--The question 'What do you think of this perfect article?'
-- is the question the poll will
--be asking.
--The date '2004-05-30' is the date the poll started.
--The date '2004-03-22 is the date designated for this poll to end.
--All dates must be in the format 'YYYY-MM-DD'.
--Example of adding a response that can be chosen by the poll-ee.
INSERT INTO pollresponses VALUES (1, 1, 1, 'It''s absolutely amazing!', 0);
--The first 1 is the number of the response out of all the responses for
-- all the polls.
--This is the primary key.
--The second 1 is the number of the primary key of the poll
-- that this will be a response to.
--The third 1 is the number to order the responses that will
-- appear within the specific poll that the response belongs to.
--'It''s absolutely amazing' is the text of the response
--The 0 is the amount of votes the response has. This number
--should ALWAYS start at zero, and will be changed by the PHP script.
--Adding another response:
INSERT INTO pollresponses VALUES (2,1,2, 'It''s good', 0);
|
现在您已经配置好了这些表,接下来可以通过在浏览器中显示用于投票的 Web 页面来检验整个系统。 用 PHP 连接到数据库 当 Web 浏览器请求 PHP 脚本时,运行在 Apache 服务器中的 PHP 模块便将这些脚本呈现为 HTML 形式。下面第一个简单的脚本将打开一个数据库连接,并向浏览器发送消息确认该连接。也可以从命令行用 php 命令来运行。 该环境的 userid 是 phpweb,而不是 dbadm或 root user。有特权的帐户应该只在必要的时候才使用特权,一般生产环境下不要用。请不要用 phpweb1 作为生产环境的口令!
清单 2. 用于通过 PHP 打开数据库连接的示例脚本
<?php
$dbname = "PHPWEB";
$username = "phpweb";
$password = "phpweb1";
// odbc_pconnect returns 0 if the connection attempt fails
// otherwise it returns a connection ID used by other ODBC functions
echo ( "attempt connect.....\n " );
$conn = odbc_pconnect ( $dbname, $username, $password );
if ( $conn == 0 ) {
echo ( "Connection to database failed." );
//If connection failed, show what the error message was:
$sqlerror = odbc_errormsg ( $conn );
echo ( $sqlerror );
}
echo ( "connect ok" );
?>
|
在 Apache 服务器环境下运行该 PHP 程序时,将产生如下屏幕:
图 3. 测试连接屏幕
![]()
如果这次测试能够正常运行,那么现在就可以安装和运行投票系统的 PHP 代码了。 PHP 投票工具 投票工具分为两部分,一是实际的投票脚本,一是维护工具。您将分别探索这两部分。 运行投票的代码在 zip 文件中。这个 zip 文件包括投票脚本和用于管理选票的工具。为了满足您的需要,您需要对这些脚本做一些更改。 投票脚本 “投票脚本”包括: index.php 文件,该文件或者是将用户带到可以选择对哪一项选票进行投票的地方,或者将他们带到投票屏幕,只对惟一给出的选票进行投票。 choosevote.php 文件,该文件允许用户从一个列表中选择投哪一票。 vote.php 文件,该文件是图 4 中显示的投票屏幕。 pollresults.php 文件,该文件允许用户查看投票结果,却不允许他们真正投票。 - processvote.php 文件,该文件通过更新数据库来处理用户的投票,然后显示结果。
运行投票屏幕(vote.php)所得到的输出如下:
图 4. 示例投票屏幕
![]() 按下投票按钮时,处理过程进入到 processvote.php 脚本。这将更新数据库表。 如何将新选票添加到 Web 站点呢?您不能期望使用投票系统的公众编写 SQL 语句来管理表中的问题和应答。 选票维护的一种较优雅的解决方案是提供管理 Web 投票的 Web 页面。现在,在下一节中研究如何在不离开 Web 浏览器的情况下进行选票维护。 维护脚本 “维护脚本”包括: poll-create1.php、poll-create2.php 和 poll-create3.php 文件,这些文件是用来创建选票的工具。 poll-drop1.php 和 poll-drop2.php 文件,它们是用来删除选票的工具。 - poll-manage1.php 文件,该文件是所有这些工具的“主页”。该页面提供了所有选票的一份详细列表,并插入了创建、删除和投票工具的链接。
选票管理包括创建和销毁选票。创建选票的工具有 3 个屏幕。图 5 中给出了选票创建工具的一个屏幕快照。 下面显示的维护屏幕大多数是无需解释的。这些屏幕的源代码在 zip 文件中。每个图的标签都包括 php 文件的名称。这样,在查看 zip 文件中的源代码时,就会更容易一些。
图 5. 主维护工具 —— poll-manage1.php
图 6. 第一个选票创建工具屏幕 —— poll-create1.php
图 7. 选票删除工具 —— poll-drop1.php
![]()
投票背后的玄机 您已经看到了投票系统的两个不同的部分,也看过了实现这两个部分的文件,现在请看一看实现这些页面的源代码。同样,您将分别看到两个部 分。 投票脚本 当用户来到 Web 站点时,他们碰到的第一个页面便是一个投票脚本,在这里是 index.php。index.php 将连接到数据库,并查看选票数据库中有多少未过期的条目。如果只有一个条目,那么该页面会将用户带到 vote.php 页面,让他们对这一项选票进行投票。否则,主页面会将用户带到 choosevote.php,让用户或者选择对多项选票中的哪一项进行投票,或者让他们知道当前没有选票。index.php 的源代码如清单 3 所示:
清单 3. index.php 的源代码
<?php
$dbname = "PHPWEB";
$username = "phpweb";
$password = "phpweb1";
$dbh = odbc_pconnect ( $dbname, $username, $password );
$today = date("Y-m-d");
$sql = "select * from polls where pollenddate > '$today' order by pollkey";
$pollexec = odbc_exec($dbh , $sql);
$rows = odbc_num_rows($pollexec);
//if there is one current poll
if ($rows == "1")
{
//sends the user to vote on that poll
$data = odbc_fetch_object($pollexec);
header("Location: vote.php?pollkey=$data->POLLKEY");
exit;
}
//if there is more than one or zero current polls
else
{
//sends the user to choosevote.php
header("Location: choosevote.php");
exit;
}
?>
|
如前所述,用户可以从 index.php转到两个地方,或者进入 vote.php页面,或者进入 choosevote.php页面。但是,如果因为有多项选票而导致用户进入了 choosevote.php,那么一旦他们单击某个链接,就会被带到 vote.php。如果用户进入 vote.php中,他们就可以进行投票,或者可以查看当前的结果。由于投票脚本更为有趣(也更复杂),所以我们将更详细 地查看该脚本。这个名为 processvote.php 的脚本通过将投票添加到数据库中来处理用户的投票,并像 pollresults.php那样显示结果。processvote.php 的源代码(32 行)可以在下方的清单 4 中找到。 |