mod_perl设置中多个区域设置之间的冲突?

mod_perl设置中多个区域设置之间的冲突?,perl,internationalization,mod-perl,mason,Perl,Internationalization,Mod Perl,Mason,我目前正在对一个大型Perl/Mason web应用程序(Perl 5.8.0、Mason 1.48、mod_Perl和Apache)进行国际化。在选择本地化模块时,我决定使用over Locale::Maketext,主要是因为后者的复数形式支持没有我想要的那么好 我对Locale::TextDomain的一个障碍是,它根据进程的Locale解析用于翻译的目录。当我意识到这一点时,我开始担心如果我想让用户能够使用不同的语言环境,这会对我的应用程序产生怎样的影响——语言环境的改变是否会影响另一个

我目前正在对一个大型Perl/Mason web应用程序(Perl 5.8.0、Mason 1.48、mod_Perl和Apache)进行国际化。在选择本地化模块时,我决定使用over Locale::Maketext,主要是因为后者的复数形式支持没有我想要的那么好

我对Locale::TextDomain的一个障碍是,它根据进程的Locale解析用于翻译的目录。当我意识到这一点时,我开始担心如果我想让用户能够使用不同的语言环境,这会对我的应用程序产生怎样的影响——语言环境的改变是否会影响另一个用户的会话?例如,是否存在这样一种情况,即英语用户收到德语页面是因为德语用户的会话更改了进程的语言环境?我不太了解Apache的线程/进程模型是如何工作的,尽管看起来如果同一个线程可以为多个用户提供服务,这可能会发生

将表明这是可能的;OP描述了我正在考虑的情况

如果这是真的,在仍然使用Locale::TextDomain的情况下,有没有办法防止这种情况发生?我想我总是可以破解模块,以独立于区域设置的方式加载目录(可能使用DBD::PO),但希望我只是缺少了一些可以解决我的问题的东西…

您可以通过使用来完全避免
setlocale
问题

(邮件列表上的这条消息比添加该功能早了大约4年。)


编辑:全局行为在Apache子系统中持续存在,导致出现错误,这是正确的

我写了一个测试用例:

app.psgi

use 5.010;
use strictures;
use Foo::Bar qw(run);

my $app = sub {
    my ($env) = @_;
    run($env);
};
Foo/Bar.pm

package Foo::Bar;
use 5.010;
use strictures;
use Encode qw(encode);
use File::Basename qw(basename);
use Locale::TextDomain __PACKAGE__, '/tmp/Foo-Bar/share/locale';
use Locale::Util qw(web_set_locale);
use Plack::Request qw();
use Sub::Exporter -setup => { exports => [ 'run' ] };

our $DEFAULT_LANGUAGE = 'en'; # untranslated source strings

sub run {
    my ($env) = @_;
    my $req = Plack::Request->new($env);
    web_set_locale($env->{HTTP_ACCEPT_LANGUAGE}, undef, undef, [
        map { basename $_ } grep { -d } glob '/tmp/Foo-Bar/share/locale/*'
    ]); # XXX here
    return $req
        ->new_response(
            200, 
            ['Content-Type' => 'text/plain; charset=UTF-8'],
            [encode('UTF-8', __ 'Hello, world!')],
        )->finalize;
}
该应用程序作为PerlResponseHandler运行。当用户请求一种无法设置的语言时,调用将以静默方式失败,并且上次成功使用的语言仍处于启用状态

解决这个问题的诀窍是始终设置为具有回退机制的语言。在标记为XXX的位置,添加代码
或web\u set\u locale($DEFAULT\u LANGUAGE)
,这样即使使用全局设置,行为也无法持续,因为我们保证每个请求都会设置/更改一次



编辑2:进一步的测试表明它不是线程安全的,对不起。仅使用将请求隔离为进程的
prefork
MPM;但是
worker
event
会受到影响,因为它们是基于线程的。

除了CPAN页面上说web\u set\u区域设置是线程安全的以外,还有其他文档吗?根据该链接的文档,web_set_locale调用locale::Util::set_locale,其文档指定它使用POSIX::setlocale——我的印象是web_set_locale实际上并没有解决这个问题,但我可能遗漏了一些重要的东西。