我有一个 mod_perl 的 HTTP 请求处理程序,它需要%ENV
在模块加载时从 读取环境变量。PerlSetEnv
使用指令将环境变量从 Apache 配置传递到 mod_perl 。
这工作得很好,直到我们出于性能原因将 Apache 配置更改为在启动时自动加载处理程序。当模块像这样自动PerlSetEnv
加载时,在模块加载时不会生效,我们需要的变量只能%ENV
在处理程序方法内部的请求时获得。
有没有办法继续使用 AutoLoad,但仍然在 Apache 配置中设置一个环境变量,该变量在%ENV
模块加载时在 Perl 中可用?
最小的例子:
这是一个精简的测试用例来说明问题。
未启用自动加载的 Apache 配置:
PerlSwitches -I/home/day/modperl
<Location /perl>
SetHandler modperl
PerlSetEnv TEST_PERLSETENV 'Does it work?'
PerlResponseHandler ModPerl::Test
Allow from all
</Location>
/home/day/modperl/ModPerl/Test.pm 的内容:
package ModPerl::Test;
use strict;
use warnings;
use Apache2::RequestRec ();
use Apache2::RequestIO ();
use Apache2::Const qw(OK);
my %ENV_AT_MODULE_LOAD = %ENV; # Take a copy
sub handler {
my $r = shift;
$r->content_type('text/plain');
$r->print("ENV:\n");
foreach my $key (sort keys %ENV) {
$r->print(" $key: $ENV{$key}\n");
}
$r->print("ENV_AT_MODULE_LOAD:\n");
foreach my $key (sort keys %ENV_AT_MODULE_LOAD) {
$r->print(" $key: $ENV_AT_MODULE_LOAD{$key}\n");
}
return OK;
}
1;
在浏览器中查看 localhost/perl 时,我看到:
ENV:
MOD_PERL: mod_perl/2.0.5
MOD_PERL_API_VERSION: 2
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
TEST_PERLSETENV: Does it work?
ENV_AT_MODULE_LOAD:
MOD_PERL: mod_perl/2.0.5
MOD_PERL_API_VERSION: 2
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
TEST_PERLSETENV: Does it work?
万岁! TEST_PERLSETENV
如我们所愿,在模块加载时可用。
但是当我们更改 Apache 配置以启用 Autoload 时(通过在 PerlResponseHandler 中使用 + 像这样):
PerlResponseHandler +ModPerl::Test
我得到以下输出:
ENV:
MOD_PERL: mod_perl/2.0.5
MOD_PERL_API_VERSION: 2
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
TEST_PERLSETENV: Does it work?
ENV_AT_MODULE_LOAD:
MOD_PERL: mod_perl/2.0.5
MOD_PERL_API_VERSION: 2
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
嘘! TEST_PERLSETENV
在模块加载时不再可用:(如何在保持 AutoLoad 行为的同时取回它?