65.9K
CodeProject 正在变化。 阅读更多。
Home

Perl 留言簿

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.50/5 (8投票s)

2002 年 9 月 25 日

CPOL

5分钟阅读

viewsIcon

532417

downloadIcon

998

本文介绍了如何使用 Perl 创建一个留言簿脚本。数据存储在 MySQL 表中,而不是平面文件中。使用 DBI 连接数据库。

Sample Image - perlguestbook.gif

Sample Image - perlguestbook.gif

引言

市面上有很多 Perl 留言簿,其中许多将数据存储在平面文件中。大多数使用 MySQL 作为后端的留言簿脚本都是用 PHP 编写的。这个留言簿是为所有想要一个将数据存储在数据库中而不是平面文件中的留言簿的 Perl 用户准备的。

我还写这个脚本是为了学习一点关于 DBI 的知识,它是 Perl 的数据库独立接口。尽管 DBI 提供了多个数据库引擎的抽象接口,但我使用了特定于 MySQL 的 SQL 语法。因此,此代码在不同数据库之间不是完全可移植的。

另外,虽然我会提到一些 DBI 的具体细节,但一个完整的 DBI 教程超出了本文的范围。欲了解更多信息,请访问 DBI 主页[^]。

特点

  • 当条目超过一页时(默认每页 10 条),显示分页链接
  • 数据存储在 MySQL 数据库中
  • 显示发帖日期、访客姓名、地点、电子邮件地址、URL 和留言。还跟踪访客 IP。

MySQL 客户端配置文件

为了从 Perl 脚本连接到 MySQL 服务器,您必须提供有效的 MySQL 用户名、密码和主机名(以及其他信息)。出于安全原因,我选择将这些数据项存储在 Web 服务器文档根目录之外的一个文件中。我称之为 includes 文件夹。例如,如果您的文档根目录位于 /home/joeuser/www/,您会将文件存储在 /home/joeuser/includes/。无论您决定将其放在哪里,都必须在实际脚本中指定其路径。

此文件的名称是 perlgb.cnf,其格式必须如下:

[client]
host=localhost
user=your_username
password=your_password

host 通常是 localhost,除非您连接到单独的数据库服务器。user 是您的 MySQL 用户名,password 是您的 MySQL 密码。您必须编辑这些值以适应您的配置。

perl_gb MySQL 表

perl_gb 包含与留言簿条目相关的所有数据。该表包含以下字段:

message_id 一个唯一的、自动递增的、非空的整数
post_date 条目发布的日期和时间
first_name 访客的名字
last_name 访客的姓
city 访客所在的城市
状态 访客所在的州
country 访客所在的国家
email_addr 访客的电子邮件地址
url 访客的 URL(可选)
ip_address 远程用户的 IP 地址
注释 访客留下的评论

请注意,除 url 外,所有字段都是必填的。

脚本

以下部分将解释我如何使用 DBI 在 MySQL 中检索和存储数据。

设置 MySQL 连接

为了连接到 MySQL,我们使用 DBI->connect() 方法。

连接参数

DBI 需要四个连接参数来连接到 MySQL:用户名、密码、主机和数据库名。前三个将从 MySQL 客户端配置文件 perlgb.cnf 中获取。您必须在脚本中指定数据库名,如下所示:

my($host_name, $user_name, $password) = (undef, undef, undef);
my($db_name) = "your_db_name";

构造数据源

指定连接参数后,下一步是构造数据源,在下面的代码中用 $dsn 变量表示。您使用的数据库引擎类型决定了数据源的格式。
注意DBI 的大小写无关紧要,但 mysql 必须全部小写。

my($dsn) = "DBI:mysql:$db_name";
$dsn .= ":hostname=$host_name" if $host_name;
$dsn .= ";mysql_read_default_file=/path/to/perlgb.cnf";

如果您不指定主机名,MySQL 将默认为 localhost。请注意,在最后一行中,您必须指定 perlgb.cnf 文件的路径。

连接到服务器

RaiseError => 1 告诉 DBI 检查与数据库相关的错误,并在检测到错误时打印一条消息并退出。

my(%attr) = (RaiseError => 1);
my($dbh) = DBI->connect($dsn, $user_name, $password, \%attr);

如果 connect() 调用成功,则会返回一个连接句柄。按照惯例,我将其命名为 $dbh。我们可以使用此句柄对我们指定的数据库中的表运行查询。

使用 DBI 对 MySQL 运行查询

检索数据

要从 MySQL 检索数据,您必须创建一个语句句柄。按照惯例,我在代码中将其命名为 $sth。将 SQL SELECT 查询传递给 $dbh->prepare() 会返回一个供我们使用的语句句柄。我们必须调用 $sth->execute() 才能实际运行查询。在下面的示例中,我们正在计算 perl_gb 表中留言簿条目的总数。

my($sth, $count);

# Issue the query
$sth = $dbh->prepare(qq{
    SELECT COUNT(message_id) FROM perl_gb
});
$sth->execute();

# Read the results of the query, then clean up.
$count = $sth->fetchrow_array();
$sth->finish();
$count = "(Couldn't obtain count)" if !defined($count);

调用 $sth->fetchrow_array() 将返回查询返回的第一行。在这种情况下,查询只返回一行和一个字段,因此我们可以将值存储在一个标量中而不是数组中。如果查询返回的行包含多个字段,我们将不得不将行存储在一个数组变量中。

要检索多行,您必须在循环中调用 $sth->fetchrow_array()。当没有更多行可返回时,fetchrow_array() 将返回 undef

$sth->finish() 释放我们刚刚运行的查询关联的任何资源。

插入数据

使用 DBI 插入数据很简单。为此,我们使用 do() 方法。do() 在一个步骤中准备语句并执行查询。这允许我们跳过使用语句句柄的步骤。do() 返回受我们传递给它的查询影响的行数。

my($myQuery);
$myQuery  = "INSERT INTO perl_gb (first_name,last_name," .
  "city,state,country,email_addr,url,ip_address,comments)";
$myQuery .= " VALUES ($first_name, $last_name, " .
  "$city, $state, $country, $email_addr, $url," . 
  " $ip_address, $comments)";
my($rows) = $dbh->do(qq{$myQuery});

脚本的其余部分

脚本的其余部分是标准的 Perl 代码。代码没有棘手之处,因此我将不再进一步讨论。

限制

  • 专为 MySQL 设计 - 使用了特定于 MySQL 的 SQL 扩展,因此未经修改无法在其他数据库上运行。
  • 专为 Unix/Linux 设计 - 然而,稍作修改即可在 Windows 系统上运行。
  • 无管理面板 - 我满意于手动修改样式。但是,如果需求足够大,我会构建一个管理面板。

参考文献

书籍

  • Christiansen, Tom, and Nathan Torkington. Perl Cookbook. Sebastopol, CA: O'Reilly & Associates, Inc., 1998.
  • DuBois, Paul. MySQL. Indianapolis, IN: New Riders Publishing, 2000.
  • Schwartz, Randal L., et al. Learning Perl on Win32 Systems. Sebastopol, CA: O'Reilly & Associates, Inc., 1997.
  • Wall, Larry, et al. Programming Perl. Sebastopol, CA: O'Reilly & Associates, Inc., 1996.

网站

致谢

很久以前,我从一个网站上抓取了 home.gifemail.gif,但我怎么也记不起来是从哪里来的了。如果您知道它们的来源,我很乐意给予应得的表彰。

历史

  • 1.00 - 2002 年 9 月 25 日:首次公开发布
  • 1.01 - 2002 年 11 月 16 日:URL 中的 HTML 现在被转义了。感谢 moliate [^] 指出这一点。
  • 1.01 - 2004 年 3 月 25 日:已从此页面中删除实时演示链接,因为我已更改为 Windows Web 服务器。代码未进行任何更改,因此版本号未递增。
© . All rights reserved.