【发布时间】:2020-04-11 12:17:02
【问题描述】:
我的 Apache 网络服务器中有 2 个目录。
PerlModule HandlerA
PerlModule HandlerB
<Directory "/var/www/html/testa">
Options FollowSymLinks
Order deny,allow
AllowOverride All
SetHandler perl-script
PerlHandler HandlerA
</Directory>
<Directory "/var/www/html/testb">
Options FollowSymLinks
Order deny,allow
AllowOverride All
SetHandler perl-script
PerlHandler HandlerB
</Directory>
/testa 有 HandlerA,/testb 有 HandlerB。
HandlerA.pm
package HandlerA;
use strict;
use warnings;
use Apache2::Const;
use lib "/etc/apache2/a";
use MyA;
use MyX;
sub handler
{
my $r = shift;
my $str = "Handler=A MyA=" . MyA::foo () . " MyX=" . MyX::foo ();
$r->log_error ($str);
$r->content_type ("text/plain");
print $str;
return Apache2::Const::OK;
}
1;
HandlerB.pm
package HandlerB;
use strict;
use warnings;
use Apache2::Const;
use lib "/etc/apache2/b";
use MyB;
use MyX;
sub handler
{
my $r = shift;
my $str = "Handler=B MyB=" . MyB::foo () . " MyX=" . MyX::foo ();
$r->log_error ($str);
$r->content_type ("text/plain");
print $str;
return Apache2::Const::OK;
}
1;
在每个处理程序中,我使用模块的 foo。这些模块位于目录 a(用于 HandlerA)和 b(用于 HandlerB)中。
a/MyA::foo 打印 A
b/MyB::foo 打印 B
a/MyX::foo 打印 A
b/MyX::foo 打印 B
只显示一个/MyX.pm
package MyX;
sub foo
{
return "A";
}
1;
由于 MyA 和 MyB 的名称不同,因此 HandlerA 使用正确的 foo 可以正常工作。
但 MyX 并非如此。
我怎样才能使在 HandlerA 中使用 a/MyX.pm 和在 HandlerB 中使用 b/MyX.pm 成为可能? 所以它不应该按名称而是按文件位置来使用模块。
处理程序 A 的输出应该是
处理程序=A MyA=A MyX=A
HandlerB 的输出应该是
处理程序=B MyB=B MyX=B
MyX 并不总是按预期工作,而且会出现混乱。
【问题讨论】:
-
@INC和包命名空间是全局的。从第一个模块加载 MyX 后,第二次使用将是空操作(除了从已加载的 MyX 再次导入)。 -
如果你确实设法加载了第二个 MyX,你会破坏程序中期望第一个的部分,因为包命名空间是全局的。
-
我在一个包中有配置数据。工作正常,但现在我需要在同一服务器内的另一个路径上拥有应用程序的第二个实例。知道如何在不给任何配置包命名的情况下重建它吗?
-
mod_perl 是一个糟糕的框架,因为它没有这样的灵活性,你只能得到一个内置到 Apache 中的 perl 解释器。使用现代 Web 框架,您可以将两个不同的路径代理到两个单独的 Web 应用程序进程。
-
“MyX 并不总是按预期工作”——这是关键声明,您能详细说明(举例)吗?问题是,我不明白这是怎么回事:当你说
use lib '/etc/apache2/a'然后use MyX它会从a/加载MyX当然(它甚至不会看b)。所以你得到了你想要的,不是吗?那怎么会失败呢? /// 另一个选项:你能把它设为package a::MyX;并加载为use a::MyX(b也一样)?如果包的差异不足以使这一点有意义,那么无论如何它应该是一个(在一个公共位置)。