我正在使用CGI::Fast
来利用FastCGI的速度和可伸缩性,并且我还使用CGI.pm的查询字符串解析。我不使用CGI.pm不推荐使用的HTML编写功能。
在社区中停止使用CGI.pm是strongly advised,但是在我的用例中,我是否也应该考虑迁移?如果是这样,我怎么办
1)仍然使用FastCGI
2)获取查询参数
...没有采用像Dancer或Mojolicious这样的框架?
我要替换的代码只是:
while ( $main::cgi = new CGI::Fast ) {
my $name = $main::cgi->param('name');
}
我愿意与CGI::PSGI
一起使用类似Plack::Request
的东西,但是我无法看到如何精炼FastCGI功能,因为CGI::Fast
和CGI::PSGI
都想要子类CGI
的创建对象。而且我仍然需要在CGI.pm中启用CGI::Fast
。 Plack似乎需要学习很多知识来替换现在的几行代码。
答案 0 :(得分:4)
这很好地说明了PSGI是对CGI(及其相关技术,如FastCGI)的改进的一个原因。在CGI风格的程序中,代码与部署方法紧密结合,当您更改部署方法时,通常需要对代码进行相当大的更改。使用PSGI风格的程序,无论您如何部署,代码都是相同的。
您没有向我们展示任何代码,但是您谈论的是“几行代码”。所以这就是我要采取的方法。
但是您在第3步中所做的任何选择都是不可撤销的。相同的代码将在所有部署环境中工作。因此,在它们之间移动通常非常简单。
p.s。 CGI.pm并非完全不推荐使用。它已从标准Perl发行版中删除,但这是因为不鼓励使用它。
答案 1 :(得分:4)
这是帮助您入门的简短指南。我将使用CGI,而不是FastCGI,但这确实是一样的。只需想象一下围绕参数选择的循环。
让我们从一个简单的CGI程序开始。由于缺少真正的Web服务器,我将使用cgi_this
来运行它。
#!/usr/bin/env perl
use strict;
use warnings;
use CGI;
my $q = CGI->new;
my $name = $q->param('name');
print $q->header;
if ($name) {
print <<"HTML";
<html><body><h1>Hello, $name</hi></body></html>
HTML
}
else {
print <<"HTML";
<html><body><form method="GET">
<label>What's your name? <input type="text" name="name"></label>
</form></body></html>
HTML
}
1;
这是 hello.pl 。它需要一个可执行标志。
您以cgi_this
开头,如下所示。
$ ls
hello.pl
$ cgi_this
Exporting '.', available at:
http://127.0.0.1:3000/
Found the following scripts:
http://127.0.0.1:3000/hello.pl
现在您可以在浏览器中打开它。
如果输入名称并提交表单,它将显示问候语。
所有这些都是直截了当的。现在,将其转换。
我们将从一个名为 hello.psgi 的新文件开始。名为 .psgi 并不重要,但这是约定。
我们必须执行几个步骤才能使其与PSGI协议兼容。我们将使用Plack::Request来帮助我们做到这一点。
整个程序需要包装在my $app = sub { ... };
调用中。
#!/usr/bin/env plackup
use strict;
use warnings;
use Plack::Request;
my $app = sub {
my $env = shift; # this is the Plack environment
my $req = Plack::Request->new($env);
my $q = CGI->new;
my $name = $q->param('name');
print $q->header;
if ($name) {
print <<"HTML";
<html><body><h1>Hello, $name</hi></body></html>
HTML
}
else {
print <<"HTML";
<html><body><form method="GET">
<label>What's your name? <input type="text" name="name"></label>
</form></body></html>
HTML
}
};
# no 1; here, we want it to return $app;
现在显然我们还没有加载CGI,并且也没有CGI环境。因此,接下来我们需要获取参数。摆脱$q
位,改用$req
。
my $name = $req->parameters->{name};
现在使用plackup
运行它,然后在http://localhost:5000上请求它。
$ plackup hello.psgi
HTTP::Server::PSGI: Accepting connections at http://0:5000/
<html><body><form method="GET">
<label>What's your name? <input type="text" name="name"></label>
</form></body></html>
Response should be array ref or code ref: 1 at ...
B!它失败了,因为我们还没有完成。如您所见,它将HTML写入了STDOUT,但这并没有传递给浏览器。这是因为PSGI会绕过引用,并且您的程序不会直接与STDOUT或STDERR通信。
它也抱怨缺少参考。让我们先处理一下。在代码参考的末尾,添加以下内容:
# prepare the response
my $res = $req->new_response(200);
$res->content_type('text/html');
return $res->finalize;
我们要我们的Plack :: Request为我们创建一个新的Plack :: Response,设置内容类型,并将最终的(认为是 immutable )响应返回给Plack处理程序,将序列化并作为实际的HTTP响应发送到浏览器。
现在替换所有print
语句。创建一个新变量$content
,而不是print
处理输出,将其连接到该变量。然后将其交给响应。
my $content;
if ($name) {
$content .= <<"HTML";
<html><body><h1>Hello, $name</hi></body></html>
HTML
}
else {
$content .= <<"HTML";
<html><body><form method="GET">
<label>What's your name? <input type="text" name="name"></label>
</form></body></html>
HTML
}
# prepare the response
my $res = $req->new_response(200);
$res->content_type('text/html');
$res->body($content);
现在,在终端中重新启动您的应用,然后再次访问它。看起来和CGI一样。
答案 2 :(得分:3)
CGI::Alternatives是解决之道。
Dancer利用PSGI,但您可以write code using it directly,而无需使用框架。
您可以使用Plack::Handler::FCGI通过FastCGI运行PSGI应用。