繁体   English   中英

多个CGI Perl脚本

[英]Multiple CGI Perl scripts

这是一个理论问题。 我正在尝试基于生产者 - 消费者范例开发Perl应用程序。 其中一个脚本创建一个包含数据的文件,而另一个脚本读取数据并且必须在HTML中显示。 还有第三个文件,一个HTML表单,它启动生产者perl文件。

我不知道是怎么跑兼顾生产者和使用CGI同时消费者,我不能在网上找到关于它的信息(至少不是我怎么寻找它)。

我想知道你是否可以告诉我在哪里可以找到这种信息,以便我可以在Apache服务器上测试应用程序。

提前致谢

您可以use Module_Name;导入模块use Module_Name; 或者require Module_Name; 在你的CGI脚本中。 http://perldoc.perl.org/functions/use.html http://perldoc.perl.org/functions/require.html

Plack网络框架不是银弹,CGI没有死,FCGI是所有速度所在的地方。

不要买入普拉克炒作。 了解它的第一个!

免责声明:我认为这个问题归结为如何让程序的两个不同组件相互交互,以创建一个可从Web访问的应用程序。 如果那不是你想要的,那就把它作为思考的食物吧。

通用网关接口

您在谈论您的问题中的CGI脚本。 (强调我的)。

我正在尝试基于生产者 - 消费者范例开发Perl 应用程序 其中一个脚本创建一个包含数据的文件,而另一个脚本读取数据并且必须在HTML中显示。

通常, CGI以请求通过Web服务器的方式工作,并传递给应用程序。 该应用程序可能是用Perl编写的。 如果它是Perl脚本,则该脚本由perl解释器运行。 Web服务器启动该过程。 它可以通过CGI访问请求信息,CGI主要是环境变量。 完成此过程后,它会将数据写入STDOUT,Web服务器将其作为响应并发回。

+-----------+        +-------------+                     +----------------+
|           | +----> |             | +-----Request-----> |                |
|  Browser  |        | Web server  |                     |  perl foo.cgi  |
|           | <----+ |             | <-----Response----+ |                |
+-----------+        +-------------+                     +----------------+

现在因为Web服务器后面只涉及一个进程,所以不能有两个脚本。 服务器无法同时与两件事进行通信。 这不是CGI的工作方式。

综合方法

相反,您需要将两个脚本包装到单个入口点并将它们转换为某种组件。 然后你可以让他们在内部互相交谈,而在外面,Web服务器只等待一个程序完成。

+-----------+        +-------------+                     +-----------------+
|           | +----> |             | +-----Request-----> |                 |
|  Browser  |        | Web server  |                     |  perl foo.cgi   |
|           | <----+ |             | <-----Response----+ |                 |
+-----------+        +-------------+                     | +-------------+ |
                                                         | |  Producer   | |
                                                         | +-----+-------+ |
                                                         |       |         |
                                                         |       |         |
                                                         |       V         |
                                                         | +-------------+ |
                                                         | | Consumer    | |
                                                         | +-------------+ |
                                                         |                 |
                                                         +-----------------+

要将其转换为Perl,我们首先确定一些术语。

  • script :一个.l文件中的Perl程序,它没有自己的package
  • module :一个位于.pm文件中的Perl模块,它具有一个package适合文件名的命名空间的package

假设您有两个我们称之为producer.plconsumer.pl的 Perl脚本。 它们大大简化,不考虑任何参数。

producer.pl

#!/usr/bin/perl
use strict;
use warnings 'all';
use CGI;

open my $fh, '>', 'product.data' or die $!;
print $fh "lots of data\n";
close $fh;

consumer.pl

#!/usr/bin/perl
use strict;
use warnings 'all';
use CGI;

my $q = CGI->new;
print $q->header('text/plain');

open my $fh, '<', 'product.data' or die $!;
while my $line (<$fh>) {
    print $line;
}

exit;

这是简化得到的。 有一个脚本可以创建数据,另一个脚本可以使用它。 现在我们需要在不实际运行它们的情况下进行这两个交互。

让我们继续前进并假设我们已经重构了这两个脚本并将它们转换为模块。 我们稍后会看到它是如何工作的。 我们现在可以在新的foo.pl脚本中使用这些模块。 它将处理请求,向生产者询问数据并让消费者将数据转换为读者想要的格式。

foo.pl

#!/usr/bin/perl
use strict;
use warnings 'all';
use Producer; # this was producer.pl
use Consumer; # this was consumer.pl
use CGI;

my $q = CGI->new;

my $params; # those would come from $q and are the parameters for the producer

my $product = Producer::produce($params);
my $output = Consumer::consume($product);

print $q->header;
print $output;

exit;

这非常简单。 我们从CGI读取参数,将它们传递给生产者,并将产品传递给消费者。 这给了我们输出,我们打印输出,然后返回服务器,发送响应。

我们来看看如何将两个脚本转换为简单的模块。 那些不需要面向对象,尽管这可能是首选。 请注意,文件名的拼写现在是不同的。 模块名称通常以大写字母开头。

Producer.pm

package Producer;
use strict;
use warnings 'all';

sub produce {
    my @args = @_;

    return "lots of data\n";
}

1;

Consumer.pm

package Consumer;
use strict;
use warnings 'all';

sub consume {
    my ($data) = @_;

    return $data; # this is really simple
}

1;

现在,如果调用正确的函数,我们有两个与脚本相同的模块。 我所做的就是在顶部放置一个命名空间( package ),并将代码包装在一个sub 我也删除了CGI部分。

在我们的示例中,生产者没有必要写入文件。 它只能返回数据结构。 消费者反过来不需要从文件中读取。 它只需要一个带有数据结构的变量,并为它提供东西来呈现它。

如果你坚持使用一致的函数名称(比如produceconsume ,就更好),你甚至可以编写多个生产者或消费者。 我们在这里基本上定义了一个接口。 这使我们有可能在不破坏兼容性的情况下重构代码的内部,但也可以坚持完全不同的生产者或消费者。 只要您坚持使用界面,就可以从单行字符串生成器切换到在心跳中查找数据库中的内容的生成器。

基本上,我们刚刚做的也可以这样显示:

+--foo.pl---------------------------+
|                                   |
|  +------+        +-------------+  |
|  |      | +----> |             |  |
|  |      |        |  Producer   |  |
|  |      | <----+ |             |  |
|  | main |        +-------------+  |
|  | foo  |                         |
|  | body |        +-------------+  |
|  |      | +----> |             |  |
|  |      |        |  Consumer   |  |
|  |      | <----+ |             |  |
|  +------+        +-------------+  |
|                                   |
+-----------------------------------+

这可能看起来有点熟悉。 它本质上是模型 - 视图 - 控制器 (MVC)模式。 在Web环境中,模型和视图通常只通过控制器相互通信,但它几乎相同。

我们的制作人是一个数据模型 消费者将数据转换为用户可以看到的网站,因此它就是视图 foo.pl中的主程序将两者粘合在一起控制着数据流。 这是控制器

触发整个事物的初始网站可以是程序的一部分,如果没有传递参数则显示,或者可以是独立的.html文件。 随你(由你决定。

所有这一切都可以用普通的旧CGI实现。 您不需要使用任何Web框架。 但随着您的应用程序的发展,您将看到现代化的框架使您的生活更轻松。


使用http://asciiflow.com/创建的图表

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM