在我的Perl CGI脚本中打印HTML后,我该怎么做?

4

在使用Perl CGI脚本打印HTML后,应该调用什么?我看到过空的return语句、exit语句,有时甚至什么都没有。这会有影响吗?

#!perl

print "Content-type: text/html\n\n";
print <<'END_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>
<title>Hello world!</title>
</head>
<body>
    <h1>Hello world!</h1>
</body>
</html>
END_HTML

# do anything else here?
# return;
# exit;

更新

假设您有一些测试,在其中打印的HTML不是在文件的末尾。在这种情况下,调用退出(exit)还是返回(return)更清晰,以表明脚本应该在那个时候结束呢?我知道这不是编写此内容的最佳方式,请就问题本身回答。

#!perl

use CGI;
my $q          = CGI->new();
my $action     = $q->param('action');

my $html_start = "Content-type: text/html\n\n";
$html_start   .= <<'END_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>
<title>Hello world!</title>
</head>
<body>
END_HTML

my $html_end = <<'END_HTML';
</body>
</html>
END_HTML

if ($action eq 'foo') {
    print $html_start;
    print '<p>foo</p>';
    print $html_end;
    # do anything else here?
}
else {
    print $html_start;
    print '<p>bar</p>';
    print $html_end;
    # do anything else here?
}
6个回答

4
你应该在输出的末尾始终打印出 "\n\n",告诉 Web 服务器输出已完成。Apache 可能会在脚本成功结束时为您执行此操作。
如果您的脚本已完成,您应该在技术上使用适当的退出状态调用 "exit" —— 成功为零,错误为非零。Web 服务器检查退出状态并呈现适当的页面(如果退出状态显示除成功以外的任何内容,则典型的错误代码为 500)。如果您没有指定 "return" 值或直接调用 exit,则 Perl(在这种情况下)将假定成功终止,并且 Web 服务器将像调用 "exit(0)" 一样处理您的 CGI 脚本。
所有这些都在 CGI 规范中描述(RFC 3875 是当前版本,如果我没记错的话)。

4
输出结果末尾不需要打印两个换行符,这只是为了将头部和正文分开。 - brian d foy

3
我猜这更多是关于编码风格而非功能的问题。如果你有一个简单、直接的程序,没有分支,那么很少有理由通过任何特殊的方式标记程序的终止:
- return 不会返回任何人可以使用的东西,因为你的程序在这里结束了 - exit 只会以状态 0 退出,这本来就会自然发生
然而,如果结构更加复杂,我建议通过某个特定的标记来标识终止点,向阅读你代码的人表明,在定义的一组条件下,不再需要考虑任何东西。
我会使用 exit 而不是 return,原因很简单,return 可能会被误认为是子过程的末尾,而 exit 明确说明程序在此处终止。

这只是一个简化的例子。假设你有一堆测试,并根据测试结果进行重定向。看到 print "Location: foo.pl\n\n"; 这行代码,你就知道在这个特定的测试中脚本到此结束了吗?如果我表达不清楚,我可以进一步解释问题。 - cowgod
请详细说明您代码的结构。如果您有许多不同的情况,在文件的物理结尾之前可以终止,我认为您应该包括一些终止标记,最好是exit... - Varkhan

1

不,这没关系。我总是让脚本自己死掉,而不是使用'return;'或'exit;',因为在Perl文档的结尾处,这些语句都没有必要,而且和'exit;'或'exit 0;'是一样的。


1
我建议使用return而非exit,这样如果您转换到CGI::Fast,您只需要将其转换为子程序即可。

0
回答你的“更新”问题:在我的当前应用程序中,我使用常见的方法来做类似这样的事情:
# UI.pm
package UI;

sub top    { print "<html><head><title>$_[0]</title><body>"; }
sub bottom { print "</body></html"; }

# All the individual .cgi files
package main;

UI::top('Welcome to my page');
print "<p>Welcome to my page!</p>";
UI::bottom();

如果你感到冒险,你可以使用hook BEGINEND来自动完成这个过程,但我不会这样做——我认为这对于一个相当小的好处来说太过繁琐了。

如果我现在必须重新开始,我不会这样做:我会更多地依赖一些中间层,比如 Catalyst,它将允许我快速地向 mod_perl 或回到 CGI。或者更好的是,从头开始编写我的应用程序以使用更多的 AJAX——这样,我的大部分“操作”都由非常小的 Perl 脚本执行,这些脚本只是处理输入并以 text/plaintext/json 的形式回应 Javascript 应用程序。


0

如果这是一个独立的事情,那么不一定需要返回或退出,这是有道理的。但如果这段代码片段在函数内部呢?它是否仍然适用?是否由于某种原因更喜欢使用返回或退出?还是只是样式问题?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接