header() 和 param() 的 CGI.pm 的替代方案?

Alternatives to CGI.pm for header() and param()?

我一直是 CGI.pm since the previous millennium so I was a bit surprised when it disappeared from my old Ubuntu server when I upgraded it recently. My short-term fix was sudo cpan install CGI, but a quick web search to find out why it was missing in the first place revealed CGI::Alternatives which explains why it has gone and offers some suggestions for alternatives. For my purposes, HTML::Tiny 的狂热用户,看起来最适合替换我的程序化 HTML 生成,但是 Alternatives 在 HTTP headers 和 CGI​​ 参数的主题上奇怪地保持沉默.

我通过搜索扩大了范围,找到了 lighter alternatives to CGI.pm on perlmonks where one response suggests CGI::Simple,但推荐度低于 whole-hearted - "its not quite as up to date as CGI.pm"。

CGI::Simple 是可行的方法,还是有更好的选择?

请不要花时间建议"rewrite everything using framework XXX"。我真的没有时间和精力。我很高兴用 HTML::Tiny 替换我所有的 HTML 代,所以我正在寻找具有类似(或更低!)返工量的东西来替换 header() 和参数().

CGI.pm 的问题不是它要消失,而是它将不再作为核心 Perl 发行版的一部分发行。然而,这并不意味着您必须从 CPAN 安装。在您的 Ubuntu 系统上,您只需执行以下操作:

sudo apt-get install libcgi-pm-perl

你会离开 运行 你熟悉和喜爱的旧 CGI :-)

如果您正在寻找提供 headerparam.

的替代方案,那么您就错过了重点

从核心(但不是从 CPAN)中删除 CGI.pm 的论点是您不必自己处理 CGI;你应该使用一个框架来为你处理这个问题。

如果您不同意这一点 — 如果您正在寻找 headerparam 的等效项 — 请继续使用 CGI.pm。

如果你同意,CGI::Simple 并不比 CGI.pm 好。

CGI::Minimal 是个不错的选择,它比 CGI & CGI::Simple 轻得多,但它缺少像 CGI & CGI::Simple

这样的高级方法

正如其他人所说,没有理由不将 CGI 与 HTML::Tiny 一起使用。这就是你问题的答案。在我使用 CGI 的最后五年里,我的程序都是这样开始的:

use CGI qw[param header];

这就是你在这里谈论的方法。

如果你等一两年,计划是从主模块中删除 HTML 生成函数,那么到那时你的问题就会全部消失。

但在你的情况下我不会这样做。我会改用 PSGI and Plack。你说你不想让任何人建议一个新的框架,所以我不会那样做。 Plack 不是一个框架,它是一个用于编写 PSGI 应用程序的工具箱。当然,我会使用像 Dancer 这样的框架,但你不必这样做。您可以愉快地使用 Plack,而无需构建在其之上的任何框架。

您仍然可以获得 PSGI 的大部分优势。您将能够以您喜欢的任何方式部署您的应用程序。您将可以访问所有出色的 Plack 中间件。测试您的程序会容易得多。

当您使用 "raw" Plack 时,CGI::param 相当于 Plack::Request::parametersCGI::header 相当于 Plack::Response::headers

所以你的问题有三个答案。

  1. 继续使用 CGI.pm。只需停止使用 HTML 生成函数并将其替换为 HTML::Tiny
  2. 使用原始 PSGI/Plack 并将您的 Web 开发带入 21 世纪
  3. 使用 Perl 的众多优秀 Web 框架之一。

很遗憾,您似乎不喜欢这些答案中的任何一个。

我的问题的正确答案是 use CGI::Simpleuse CGI qw(header param) 好,因为它加载速度更快。

类似 "Use Plack, it's the future of Perl for websites" 的回答对我没有帮助,因为我没有时间学习新的编程范式或发现如何重新配置​​我的网络服务器以使其工作,无论Plack 布道者多么坚持认为我的努力是错误的。

我现在有一些时间浏览了提供给我的文档和演示幻灯片的链接,我可以看到他们在做什么,但到目前为止我所读的内容中有一个失败的是缺少一个简明的 end-to-end 工作示例来帮助我解决问题……所以这就是我拼凑起来让我开始的东西(而且,不,我还没有完成!)。我希望开始从 CGI 到 PSGI 旅程的其他人会发现这对帮助他们开始工作很有用...

首先你需要安装Plack。我是 运行 Ubuntu 14.04 安装,所以这只是 运行 sudo apt-get install libplack-perl 的问题。来自 CPAN 的 generic way is to install Task::Plack

接下来您需要知道 cgi-bin 目录所在的位置。如果你是 CGI,你应该已经知道了 die-hard!因为我是 运行 Apache 我的是 /etc/apache2/conf-available/serve-cgi-bin.confScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ 定义的。

现在是魔术。我们将创建一个运行 PSGI 应用程序的 CGI 脚本,将来自 CGI 环境的数据传递给它。这有利于实验和测试,但不适用于部署,因为您不会获得 PSGI 可以为您提供的任何速度优势(为此您需要像 Plack::Handler::Apache2, Plack::Handler::FCGI or mod_psgi in Apache, or a dedicated PSGI server such as Starman or Starlet, or one of the other handlers mentioned on PlackPerl.org 这样的东西)。使用以下内容创建 /usr/lib/cgi-bin/psgi-cgi.pl 并使其可执行:-

#!/usr/bin/perl
use Plack::Util;
use Plack::Handler::CGI;
my $app = Plack::Util::load_psgi($ENV{PATH_TRANSLATED});
Plack::Handler::CGI->new->run($app);

接下来我们需要告诉 Apache 将 PSGI 应用程序文件传递给此处理程序。我通过创建包含以下内容的 /etc/apache2/conf-available/psgi-cgi.conf 来做到这一点:-

Action psgi-cgi /cgi-bin/psgi-cgi.pl
AddHandler psgi-cgi .psgi

然后通过 运行 sudo a2enconf psgi-cgisudo service apache2 reload 将其加载到我的 Apache 服务器中。基本上,您需要将这些行放入 httpd.conf 文件并重新启动服务器。

最后,我的第一个 PSGI 脚本,我在服务器的 DocumentRoot 中创建为 /var/www/html/hello.psgi:-

use Plack::Request;

my $app = sub {
    my $env = shift;
    my $req = Plack::Request->new($env);
    my $par = $req->parameters;

    return [
        200,
        [ 'Content-Type', 'text/plain' ],
        [ "Hello world!\n",
          map("$_ = ".join(", ", $par->get_all($_))."\n", sort keys %$par),
        ]
    ];
};

应用程序是一个代码引用,其中 returns 一个 3 元素数组引用:第一个是 HTTP 状态代码,第二个是 HTTP header 的名称、值对,第三个是响应的 body(可以使用 HTML::Tiny for a web page). The first 2 elements answer the question of what you need instead of the CGI::header function - nothing! (though for more complex handling you'll need Plack::Response::headers). The example also shows how to replace CGI::param - use Plack::Request::parameters, which returns a Hash::MultiValue object 生成,其中包含 URL (GET) 和 BODY (POST) 的值参数,包括具有多个值的参数。

最后,一个测试:-

$ wget -q -O- 'http://localhost/hello.psgi?a=1&a=2&a=3&b=1&b=4'
Hello world!
a = 1, 2, 3
b = 1, 4

我希望这对其他 CGI die-hard 迈出精通 PSGI 的第一步有用,我希望 Plack Evangelists 承认需要大量阅读和理解才能走到这一步.