当前位置: 首页 > 知识库问答 >
问题:

使用PHP Gettext而无需安装区域设置

宣意致
2023-03-14

我一直在寻找开源项目国际化的选项:

>

  • Gettext,似乎每个人都推荐,显然需要在您的系统上安装区域设置才能使用。请参阅PHP手册上的此注释,它正好反映了我的情况。这个SO问题也问了同样的问题。这不适合开源项目,因为我不能相信最终用户在他们的系统上安装了适当的区域设置。此外,这是非常非常奇怪的,你必须安装区域设置只是为了使用字符串,你已经翻译(IMO)。

    Zend_Translate有时也建议支持gettext,但我没有使用Zend框架,所以我认为它不是我的选择。有人说你可以把它从Zend框架中分离出来,但我不知道怎么分离。如果有人能告诉我需要哪些文件(我下载了一个Zend框架的tarball)来挑选,我愿意使用Zend_Translate。

    数组。这就是我现在正在做的,但并不理想,因为:

    • 定义每一个翻译都会占用大量内存,而当前页面不会使用大部分内存

    我可以以某种方式读取. mo文件没有Gettext或Zend_Translate,还是必须使用Gettext?如果是这样,我如何使所有区域设置工作,就像我上面链接到的问题一样?

    编辑:我现在愿意使用Zend_Translate。我只需要弄清楚我需要什么文件(如果它们可以合并成一个文件那就太好了)——我不希望整个Zend框架出现在我的项目中。

    更新:我很想看看大型开源项目如何处理i18n:

    • Moodle使用数组
    • Drupal似乎使用数组,并使用数据库回退。它们还运行setlocale('C'),以获得通用的区域设置,并绕过整个setlocale混乱
    • Wordpress为i18n使用了大量自己的函数,尽管下面确实使用了gettext

    就我所见,这三个随机项目中没有一个直接使用Zend_Translate,也没有一个直接使用gettext。

    也许最好使用Clocale,将语言名称存储在文本域名中,然后从那里开始。

    所以就我而言:

    $lang = 'de'; //debug
    setlocale( LC_ALL, 'C' );
    bindtextdomain( 'default', PATH . "/locale/$lang" );
    bind_textdomain_codeset( 'default', 'UTF-8' );
    textdomain( 'default' );
    
    var_dump( file_exists( PATH . "/locale/$lang/C/LC_MESSAGES/default.mo" ) ); //bool(true)
    

    但是我仍然只是得到了英文字符串,即使我已经使用了poedit、msgfmt等来制作相应的文件。我也尝试过重启Apache。

  • 共有3个答案

    单于奕
    2023-03-14

    对于任何对此仍然有问题的人,你可以尝试下面的代码,我从这里得到:http://php.net/manual/en/function.gettext.php#58310

    它在freebsd服务器上解决了我的问题,没有额外的语言环境安装(fr\u fr和my\u my)。当您遇到gettext缓存问题时,此代码也很有用。

    <?php
    function initialize_i18n($locale) {
      $locales_root="/app/php/locale"; // change This to where you locale folder at
      putenv('LANG='.$locale);
      setlocale(LC_ALL,"");
      setlocale(LC_MESSAGES,$locale);
      setlocale(LC_CTYPE,$locale);
      $domains = glob($locales_root.'/'.$locale.'/LC_MESSAGES/*.mo');
      $current = basename($domains[0],'.mo');
      $timestamp = preg_replace('{messages-}i','',$current);
      bindtextdomain($current,$locales_root);
      textdomain($current);
    }
    ?>
    
    王子明
    2023-03-14

    以下是解决方案:

    $lang = 'de'; //debug
    setlocale( LC_ALL, 'C.UTF-8' );
    bindtextdomain( 'default', PATH . "/locale/$lang" );
    bind_textdomain_codeset( 'default', 'UTF-8' );
    textdomain( 'default' );
    

    这与我在答案底部发布的示例之间的唯一区别是,它使用C.UTF-8而不仅仅是C

    我将对此进行更多测试,如果它跨平台工作,并且如果我发现任何其他问题,将更新此答案。

    茅和玉
    2023-03-14

    试试gettext php。这是用PHP编写的gettext的一个临时替代品。我认为,它最初是为WordPress完成的,因为WP需要在共享主机上运行,而共享主机并不总是针对每个语言环境进行配置。在我看来,这也是你的问题。

    它的性能受到了一些冲击,但对我来说根本不是问题。

     类似资料:
    • 问题内容: 最近,我对于是否可以直接发送输入/文本区域数据而不包含在html 中感到困惑。我想在网页上,如果我们想从用户那里获取信息,然后将文本发送到身份验证服务器,则无论使用哪种方式提交,都必须使用。 但是我的论文的一位匿名审稿人声称,可以使用html5标签“ textarea”和JS AJAX帖子来绕过。虽然我做了很多尝试来实现他的方法的实验,但是都失败了。 我想知道是否真的有某种方式可以在不

    • 我想强制我的Symfony 2.5应用程序的区域设置为。我希望这个区域设置用于strftime()函数。 我的: 我正在我的一个控制器中使用以下代码来调试: 当这样执行时,它显示:。 但是,当第一行未注释时,它会显示:,因此区域设置已安装在系统中并正常工作。 我如何使Symfony始终使用配置中指定的语言环境? $locale-a:

    • 在安装WebLogic Server的过程中,安装向导会询问我想将域目录放在哪里。对于域目录,这是绝对路径还是相对路径?如果它是一个相对路径,它挂在哪个目录下?这是我第一次安装它,这让我怀疑我应该把它放在哪里,最好的做法是什么。谢谢你的指导。

    • 当我遇到伪造的问题时,我正在Raspberry Pi上设置一个改装的Minecraft服务器。我之前设置了一个运行1.17的香草服务器,这需要Java16,但我需要Java15或更低的伪造。我之前安装了Java16 JDK从https://adoptopenjdk.net/releases.htmlarm32架构,它运行得非常好。我试图安装服务器的伪造版本是1.16.5。我下载了安装程序,它运行得

    • 我的问题是: 我想在Android设备上导入https的根ca,但Android系统要求我设置密码/pin。设置密码/pin后,我的ci测试用例必须解锁屏幕并输入密码/pin,这很难实现。我没有做这部分工作的好主意。因此,我想问一下,是否有办法在android设备上安装https的根ca。 Ps,我在google上试过,才发现我的设备都要root,这是我最不想做的事情。 欢迎任何想法或解决方案。