28、Perl编程:面向对象与CGI脚本开发

Perl编程:面向对象与CGI脚本开发

1. 面向对象Perl编程的选择考量

在进行Perl编程时,我们常常会面临选择使用面向对象(OO)风格还是过程式风格的问题。以下是一些需要考虑的因素:
- 子程序是否为任务导向 :如果程序自然地涉及一系列无关联的任务,那么可能适合使用过程式风格。而如果应用是数据驱动的,主要处理数据结构而非任务,那么可以考虑使用OO风格。
- 是否需要数据持久化 :任务完成后,如果需要存储数据以便下次处理时使用,使用OO接口可能更方便。若每次调用子程序都是完全独立的,则可以使用过程式接口。例如,生成交叉引用表时,交叉引用子程序需要知道正在处理的内容之前是否出现过,由于对象可以封装关于数据的所有信息,因此直接处理会很容易。
- 是否需要会话管理 :如果希望使用相同的子程序处理多个不同的数据块,例如有两个不同的“会话”表示数据库连接或网络连接,将每个会话封装成对象可能会更简单。
- 是否对速度有要求 :面向对象程序通常比完成相同任务的过程式程序运行速度慢,因为将事物封装成对象并传递对象会消耗大量时间和资源。如果可以不使用面向对象编程,那么最好不要使用。
- 是否希望用户对对象无感知 :如果想隐藏事物的行为细节,OO是一个不错的方法。可以设计对象以任意方式存储数据,然后为用户提供一个易于使用的接口,用户可以在不知道对象信息实现方式的情况下使用对象。
- 仍然不确定时 :除非确定需要OO模型,否则使用过程式模型可能更有助于维护和提高代码的可读性。如果仍然不确定,建议使用普通的过程式模型。

2. 面向对象编程基础

面向对象编程是一种不同的编程思维方式,它从数据以及数据之间的关系(即对象)的角度来处理问题。这些对象属于称为类的划分,类具有属性和可以执行的操作(方法)。在Perl中,面向对象编程简洁而简单:
- 对象是被祝福到类中的引用。
- 类是普通的Perl包。
- 方法是普通的Perl子程序,类名或对象引用会被神奇地传递进去。

基于这三个基本原则,就可以开始构建数据驱动的应用程序。

以下是一个简单的练习示例,使用 Person8.pm 编写一个程序:

# 示例代码,假设Person8.pm已存在
# 创建三个不同的Person8对象
# 打印Person8对象的数量
# 遍历Person8对象并向每个对象打印一封信

# 这里只是示例框架,具体实现需要根据Person8.pm的内容
3. CGI编程基础
3.1 CGI简介

通用网关接口(CGI)是Web服务器用于运行外部程序(即CGI脚本或CGI程序)的一种方法,通常用于动态生成Web内容。每当网页查询数据库或用户提交表单时,通常会调用CGI脚本来完成工作。CGI只是一个规范,它定义了Web服务器运行此类脚本以及这些程序将结果返回给服务器的标准方式。CGI脚本的任务是读取浏览器通过服务器发送的信息,并生成某种有效的响应,通常是可见内容,但并非总是如此。脚本完成任务后,会结束并退出。

Perl是用于此目的的非常流行的语言,因为它具有无与伦比的文本处理能力、易于编写脚本和相对较快的速度。可以说,Perl目前的大部分流行度归功于其在动态网页生成方面的成功。此外,Perl有一个优秀的模块 CGI.pm ,可以轻松编写CGI脚本。

3.2 编写CGI程序的准备工作
  • 获取Web服务器访问权限 :编写CGI程序的第一步是获得对Web服务器的访问权限。可以选择在提供Web服务器的ISP处获取账户,也可以在本地机器上安装Web服务器。建议使用Apache,它是互联网上最流行的服务器,截至2010年1月,它占据了约47%的Web服务器市场。
    • 下载Apache :访问 http://httpd.apache.org/ 并点击下载链接,2010年1月的最新版本是2.2.14。
    • 安装Apache :按照 http://httpd.apache.org/docs/2.2/install.html 的安装说明进行安装。或者参考《Pro Apache, Third Edition》(作者Peter Wainwright)以快速让Apache运行起来。
    • Unix用户注意事项 :Unix系统很可能已经安装并运行了Apache。可以通过在浏览器中访问 http://127.0.0.1/ (也称为localhost)来验证机器是否准备好为Web客户端提供服务。如果看到显示Apache正在运行的响应页面,则可以开始使用。注意,如果机器没有运行Web服务器,可能会访问到 http://www.localhost.com/
    • Windows用户注意事项 :在Windows上安装Apache时,示例中使用的Perl路径 #! /usr/bin/perl 可能需要更改为Windows上Perl的安装位置,例如 #!c:/Perl/bin/perl.exe
  • 创建CGI目录 :安装Apache后,需要创建并配置一个CGI目录。具体操作可参考 http://httpd.apache.org/docs/2.2/howto/cgi.html 。该目录的位置因机器而异,常见的Unix位置有 /usr/local/apache/cgi-bin/ /home/httpd/cgi-bin/
4. 编写CGI程序

现在Apache已安装,CGI目录已配置,我们可以开始编写CGI脚本了。编写Perl的CGI脚本非常简单,甚至可以说,如果你能打印“hello, world!”,就已经成功了一半。

以下是一个简单的“hello, world!” CGI程序示例:

#!/usr/bin/perl
# hello.pl

use warnings;
use strict;

print "Content-Type: text/plain\n";
print "\n";
print "hello, world!\n";

如果该程序位于CGI目录中并具有适当的可执行权限(Unix系统中为755),可以通过在浏览器中加载 http://localhost/cgi-bin/hello.pl 来查看结果。

在这个程序中, print "Content-Type: text/plain\n"; 这行代码非常重要,它包含了后续信息的内容类型,通过HTTP头发送给客户端,告知客户端后续内容将被视为纯文本。接下来的 print "\n"; 打印一个空行,这是必需的,因为头信息后面必须跟一个空行,以便客户端知道头信息已结束,后续信息是主体内容。如果忘记打印空行,浏览器通常会显示“Server Error”消息。

5. CGI脚本问题排查

如果在浏览器中没有看到友好的问候信息,可能是CGI脚本出现了问题。以下是一些排查问题的方法:
1. 文件位置 :确保文件位于Apache正在查找的目录中。如果不是,将其移动到适当的位置并再次尝试。
2. 文件权限 :确保文件的权限设置允许服务器执行该程序。在Unix系统中,权限通常设置为755,可以使用 chmod 命令更改权限并再次测试。
3. 语法错误 :脚本可能存在语法错误。可以使用 -c 选项在命令行上执行程序来检查语法:

$ perl -c hello.pl
hello.pl syntax OK

如果显示语法错误,修复问题后再次尝试。
4. 空行检查 :空行非常重要,如果忘记打印,通常会导致服务器错误。可以在命令行上执行程序来确保空行存在:

$ perl hello.pl
Content-Type: text/plain

hello, world!

如果没有看到空行,添加额外的 \n
5. 内容类型检查 :确保内容类型是预期的。对于上述程序,应该是 text/plain
6. Apache配置检查 :可能是Apache配置不正确,这更难修复,需要阅读Apache配置文档来排查问题。
7. 查看错误日志 :当其他方法都失败时,可以查看Apache的错误日志文件(通常位于 logs 目录下的 error_log 文件中),Apache会将错误信息记录到该文件中,可能会告诉你脚本失败的原因。

如果仍然无法解决问题,可以访问 www.perlmonks.org ,这是一个很好的网站,Perl程序员可以在这里向其他Perl程序员提问并获得礼貌且有用的答案。

6. CGI环境变量

当Web服务器执行CGI程序时,会通过导出的环境变量向程序提供大量信息。在Perl程序中,可以通过 %ENV 来获取这些环境变量。

以下是一个使用 %ENV 显示服务器知道的关于请求CGI程序的客户端的几个重要信息的程序:

#!/usr/bin/perl
# env1.pl

use warnings;
use strict;

print "Content-Type: text/plain\n";
print "\n";

print "your hostname is:      $ENV{REMOTE_ADDR}\n";
print "your outbound port is: $ENV{REMOTE_PORT}\n";
print "your browser is:       $ENV{HTTP_USER_AGENT}\n";

如果在浏览器中访问 http://localhost/cgi-bin/env1.pl ,可以看到客户端的互联网地址、客户端机器的端口号以及使用的Web浏览器信息。

如果想查看服务器可用的其他环境变量,可以使用以下程序:

#!/usr/bin/perl
# env2.pl

use warnings;
use strict;

print "Content-Type: text/plain\n";
print "\n";

foreach (sort keys %ENV) {
    print "$_ = $ENV{$_}\n";
}

加载 http://localhost/cgi-bin/env2.pl 将显示所有环境变量。

7. 生成HTML内容

通常,CGI程序不会打印纯文本,而是打印HTML内容,让浏览器正确渲染。要告诉客户端CGI程序正在生成HTML,只需更改 Content-Type 即可。

以下是一个生成HTML内容的示例:

#!/usr/bin/perl
# env3.pl

use warnings;
use strict;

print "Content-Type: text/html\n";
print "\n";

foreach (sort keys %ENV) {
    print "$_ = $ENV{$_}";
    print "<br />";
}

将内容类型更改为 text/html 后,浏览器会将后续内容视为HTML并进行处理。注意,在打印环境变量及其值时,不使用换行符,因为浏览器在HTML中将其视为简单的空白字符。要实现换行,需要打印 <br /> 标签。

为了使输出更具可读性,可以将其放在表格中:

#!/usr/bin/perl
# env4.pl

use warnings;
use strict;

print "Content-Type: text/html\n";
print "\n";

print "<table border=\"1\">";
foreach (sort keys %ENV) {
    print "<tr><th>$_</th><td>$ENV{$_}</td>";
}
print "</table>";

通过查看 http://localhost/cgi-bin/env4.pl ,可以看到更清晰的输出。

8. 引入CGI.pm模块

通过前面的示例可以看出,编写CGI程序并不复杂,只需使用 print() 函数生成标准输出,记得以 Content-Type 行开头,后面跟一个空行,然后是要在浏览器中显示的内容(如文本、HTML等)。

现在介绍一个非常流行的Perl模块 CGI.pm ,它由Lincoln Stein编写,通过提供一些有用的方法,使生成HTML和处理表单数据变得容易。

首先,我们看一个不使用 CGI.pm 生成网页的程序:

#!/usr/bin/perl
# html1.pl

# this program generates HTML without the use
# of CGI.pm

use warnings;
use strict;

print "Content-Type: text/html\n";
print "\n";
print "<html>\n";
print "<head>\n";
print "<title>Generating HTML</title>\n";
print "</head>\n";
print "<body>\n";
print "<h1>Now Is:</h1>\n";
print "<p>\n";
print "The current date and time is: ";

print scalar(localtime);

print "</p>\n";
print "<hr />\n";
print "<h1>Our CGI Scripts</h1>\n";
print "<p>\n";
print "By the time this chapter is over, you will write all of \n";
print "these scripts:\n";

print "<br />$_\n" foreach <*.pl>;

print "</p>\n";
print "<h1>Go Here For Excellent Books!</h1>\n";
print "<p>\n";
print "Check out the \n";
print "<a href=\"http://www.apress.com/\">Apress Home Page</a>.\n";
print "</p>\n";
print "</body>\n";
print "</html>\n";

这个程序大部分代码只是打印HTML。其中, print scalar(localtime); 调用 localtime() 函数在标量上下文中返回计算机上当前日期和时间的可读字符串,并将其打印到标准输出,将在浏览器主体中显示。 print "<br />$_\n" foreach <*.pl>; 使用 foreach 命令的表达式修饰符形式,遍历所有匹配 *.pl 模式的文件,并为每个文件打印一个 <br /> 标签。

可以看到,大量的 print() 函数以及双引号、换行符和分号使代码的可读性较差。可以使用Here文档来改进,如下所示:

#!/usr/bin/perl
# html2.pl

# this program generates HTML without the use
# of CGI.pm - this time with a here document

use warnings;
use strict;

print "Content-Type: text/html\n";
print "\n";

print <<EOHTML;
<html>
<head>
<title>Generating HTML</title>
</head>
<body>
<h1>Now Is:</h1>
<p>
The current date and time is:
EOHTML

print scalar(localtime);

print <<EOHTML;
</p>
<hr />
<h1>Our CGI Scripts</h1>
<p>
By the time this chapter is over, you will write all of
these scripts:
EOHTML

print "<br />$_\n" foreach <*.pl>;

print <<EOHTML;
</p>
<h1>Go Here For Excellent Books!</h1>
<p>
Check out the
<a href="http://www.apress.com/">Apress Home Page</a>.
</p>
</body>
</html>
EOHTML

Here文档在打印静态文本时很有用,但在打印 scalar(localtime) 和遍历所有 .pl 文件时,需要确保这些可执行语句在Here文档之外。

接下来,我们看看使用 CGI.pm 生成相同内容的程序:

#!/usr/bin/perl
# cgi1.pl

# this program generates HTML with the use
# of CGI.pm

use warnings;
use strict;
use CGI ':standard';

print header();
print start_html('Generating HTML');
print h1('Now Is:');
print p('The current date and time is:', scalar(localtime));
print hr();
print h1('Our CGI Scripts');

my $file_listing = '';
$file_listing .= "<br />$_" foreach <*.pl>;

print p('By the time this chapter is over, you will write all of',
        'these scripts:', $file_listing);
print h1('Go Here For Excellent Books!');
print p('Check out the',
        a({ href => 'http://www.apress.com/' }, 'Apress Home Page'));
print end_html();

这个程序的前半部分和其他Perl程序类似,以 shebang 开头,后面是可选的注释、 use warnings; use strict; 。然后是 use CGI ':standard'; ,这行代码使 CGI.pm 的使用成为可能。 :standard 告诉 CGI.pm 我们希望在不使用对象调用的情况下使用模块中的方法。例如,可以直接调用 header() 方法:

print header();

而不是:

my $q = new CGI;
print $q->header();

header() 方法非常方便,它会打印头信息,即生成 Content-Type: text/html ,并且会自动生成必需的空行。 start_html('Generating HTML'); 方法生成HTML的开头部分,将参数放在 <title> 标签之间。 h1('Now Is:'); 生成 <h1>Now Is:</h1> 标签。 p() 方法生成 <p> 标签,并将参数放在标签之间,它会智能地处理多个参数,自动添加空格分隔。 hr() 方法生成 <hr /> 标签。

通过使用 CGI.pm ,代码的可读性得到了显著提高,开发效率也会相应提升。

综上所述,在Perl编程中,无论是面向对象编程的选择,还是CGI脚本的开发,都有其各自的特点和适用场景。我们可以根据具体需求灵活运用这些知识,开发出高效、易维护的程序。

Perl编程:面向对象与CGI脚本开发

9. CGI.pm模块方法详解

CGI.pm 模块提供了许多实用的方法,下面对前面示例中使用的方法进行详细解释:
| 方法名 | 功能描述 | 示例代码 | 输出结果 |
| ---- | ---- | ---- | ---- |
| header() | 打印HTTP头信息,包含内容类型和必需的空行 | print header(); | Content-Type: text/html
(后面跟一个空行) |
| start_html() | 生成HTML文档的开头部分,包括 <html> <head> <title> 标签 | print start_html('Generating HTML'); | <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head><title>Generating HTML</title>
</head><body> |
| h1() | 生成 <h1> 标题标签 | print h1('Now Is:'); | <h1>Now Is:</h1> |
| p() | 生成 <p> 段落标签,可处理多个参数 | print p('The current date and time is:', scalar(localtime)); | <p>The current date and time is: Fri Jan 18 19:02:48 2010</p> |
| hr() | 生成 <hr /> 水平分隔线标签 | print hr(); | <hr /> |
| a() | 生成 <a> 超链接标签 | print a({ href => 'http://www.apress.com/' }, 'Apress Home Page'); | <a href="http://www.apress.com/">Apress Home Page</a> |
| end_html() | 生成HTML文档的结尾部分,包括 </body> </html> 标签 | print end_html(); | </body></html> |

通过这些方法,我们可以更方便地生成HTML内容,避免了手动编写大量HTML标签的繁琐。

10. 处理表单数据

CGI.pm 模块不仅可以方便地生成HTML,还可以处理表单数据。下面是一个简单的表单处理示例:

#!/usr/bin/perl
# form.pl

use warnings;
use strict;
use CGI ':standard';

print header();
print start_html('Form Example');

if (param()) {
    my $name = param('name');
    my $email = param('email');

    print h1('Thank You!');
    print p("Your name is: $name");
    print p("Your email is: $email");
} else {
    print h1('Please Fill Out the Form');
    print start_form();
    print label({ for => 'name' }, 'Name: ');
    print textfield('name');
    print br();
    print label({ for => 'email' }, 'Email: ');
    print textfield('email');
    print br();
    print submit();
    print end_form();
}

print end_html();

在这个示例中,首先检查是否有表单数据提交( param() 函数返回非空表示有数据提交)。如果有数据提交,获取 name email 参数的值并显示感谢信息;如果没有数据提交,显示表单供用户填写。

11. 流程图:CGI脚本开发流程
graph TD;
    A[获取Web服务器访问权限] --> B[安装Apache];
    B --> C[创建并配置CGI目录];
    C --> D[编写CGI脚本];
    D --> E[调试和测试脚本];
    E --> F[部署和上线];
12. 总结

通过本文的介绍,我们了解了Perl编程中面向对象编程和CGI脚本开发的相关知识。在选择编程风格时,需要根据具体需求考虑是否使用面向对象编程。在开发CGI脚本时,我们可以使用 CGI.pm 模块来简化HTML生成和表单数据处理的过程。

以下是一些关键要点总结:
- 面向对象编程选择 :根据子程序是否为任务导向、是否需要数据持久化、会话管理、速度要求以及是否希望用户对对象无感知等因素来决定是否使用面向对象编程。
- CGI脚本开发
- 准备工作:获取Web服务器访问权限,安装Apache,创建并配置CGI目录。
- 编写脚本:使用 print() 函数生成标准输出,注意 Content-Type 和空行的使用。
- 问题排查:检查文件位置、权限、语法错误、空行、内容类型和Apache配置等。
- 使用 CGI.pm 模块:提高代码可读性和开发效率。

希望这些知识能够帮助你在Perl编程中更加得心应手,开发出高质量的应用程序。

总之,Perl作为一种强大的脚本语言,在Web开发等领域有着广泛的应用。通过不断学习和实践,我们可以充分发挥Perl的优势,实现各种复杂的功能。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值