Perl 留言簿






2.50/5 (8投票s)
本文介绍了如何使用 Perl 创建一个留言簿脚本。数据存储在 MySQL 表中,而不是平面文件中。使用 DBI 连接数据库。
引言
市面上有很多 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.gif 和 email.gif,但我怎么也记不起来是从哪里来的了。如果您知道它们的来源,我很乐意给予应得的表彰。