【问题标题】:How to use po/pot files with php?如何在 php 中使用 po/pot 文件?
【发布时间】:2011-06-08 15:24:48
【问题描述】:

我在地址为 /locale/nld_nld/LC_MESSAGES/ 的文件夹中有一个 .po 和一个 .mo 文件。这两个文件的名称都是消息。我一直在尝试使用以下代码:

try.php:

<?php
require_once("Localization.php");
echo _("Hello World!");
?>

Localization.php 放在这里:

<?php
$locale = "nld_nld";
if (isSet($_GET["locale"])) $locale = $_GET["locale"];
putenv("LC_ALL=$locale");
setlocale(LC_ALL, $locale);
bindtextdomain("messages", "./locale");
bind_textdomain_codeset("messages", 'UTF-8');
textdomain("messages");
?>

try.php 和本地化文件都在同一个目录中。另外,我使用xampp。我还实现了phpinfo();。在表格中,在“GetText Support”前面提到了启用。 messages.pomessages.mo 文件是我使用 poEdit 创建的有效文件。我是 Windows 用户。然而,当我打开 try.php 时,它只是简单地呼应了 Hello World! (不是它的翻译字符串。另外,我已将 .po 文件翻译为 100%(根据 poEdit)。不过,我没有得到结果。对此有一点帮助赞赏。

提前致谢!

【问题讨论】:

    标签: php gettext mo php-gettext po


    【解决方案1】:

    问题可能是 UTF-8 中的“-”。 为了 Windows 兼容性,还需要添加其他行。 尝试阅读:http://www.php.net/manual/en/function.setlocale.php#89076

    【讨论】:

      【解决方案2】:

      回顾我在工作网站上用于西班牙语翻译的代码时,我注意到我也有相同的行,但顺序不同,也许这会有所不同?例如:

      <?php
      putenv('LC_MESSAGES=es_ES');
      setlocale(LC_MESSAGES, 'es_ES.utf8');
      bindtextdomain('es','/full/path/here/application/locale');
      textdomain('messages-es');
      bind_textdomain_codeset('messages-es', 'UTF-8');
      ?>
      

      为了使上述代码正常工作,我的 .mo 文件位于 /full/path/here/application/locale/es_ES.utf8 文件夹中。

      也许我之前使用过的以下代码可以帮助您进一步排除故障:

      <?php
      function TestLang( $langCode ) {
        echo( '<b>TESTING LANG CODE: ' . strtolower( $langCode ) . '</b><br />' );
        putenv( 'LC_MESSAGES=' . strtolower( $langCode ) . '_' . strtoupper( $langCode ));
        echo( 'LC_MESSAGES: ' . getenv( 'LC_MESSAGES' ) . '<br />' );
        $localeResult = setlocale( LC_MESSAGES, strtolower( $langCode ) . '_' . strtoupper( $langCode ) . '.utf8' );
        echo( 'Locale: ' . $localeResult . '<br />' );
        $textDomain = bindtextdomain( strtolower( $langCode ), ROOT . '/' . APP_DIR . '/locale' );
        echo( 'Text Domain: ' . $textDomain . '<br />' );
        textdomain( strtolower( $langCode ));
        $codeSet = bind_textdomain_codeset( strtolower( $langCode ), 'UTF-8' );
        echo( 'Code Set: ' . $codeSet . '<br />' );
        echo( '.mo File: ' . $textDomain . '/' . $localeResult . '/LC_MESSAGES/' . $langCode . '.mo<br />' );
        echo( '<br />-- ' . _( 'Hello World!' ) . ' --<br />' );
      }
      
      TestLang( 'en' );
      TestLang( 'de' );
      TestLang( 'es' );
      TestLang( 'fr' );
      // etc..
      ?>
      

      【讨论】:

      • textdomain() 通常是最后一个函数调用(实际上,如果您使用多个域,则在每次 gettext aka _() 调用之前可能需要它。首先绑定所有域,然后选择一个。
      • 在您的示例中,您使用了两个不同的域名“es”和“messages-es”。这可能不起作用(通常文件名中没有语言标识符,因为它是由目录定义的)。所以“/full/path/here/application/locale/es_ES/LC_MESSAGES/messages.mo”将是域“messages”和LC_TYPE es_ES的文件名。
      【解决方案3】:

      输出$result=bindtextdomain($domain,$path)的返回值,它会告诉你你的本地路径是否确实是你希望你的翻译文件生命的路径。然后检查这些文件的文件访问权限,如果它们(以及直到根目录)可由 www 用户访问。它位于 ./locale/LC_MESSAGES/nld_nld/

      textdomain($domain) 应该是最后一种方法(在实际的 gettext 翻译之前)。 bindtextdomain 和 textdomain 的 domain 参数应该是同一个域名(你的答案中没有),并且等于 mo 文件的基本名称。

      还要确保您的 php 文件不使用另一个文本域,尤其是当您使用“require_once”时。

      顺便说一句,您的代码在请求中查找区域设置标识符(没有过滤器)并使用 nld_nld 作为默认故障回复,我将在那里放置普通语言(主要站点语言,如“en”)。

      【讨论】:

        猜你喜欢
        • 2012-04-22
        • 2019-03-26
        • 2020-01-18
        • 1970-01-01
        • 2015-11-25
        • 1970-01-01
        • 2012-01-16
        • 1970-01-01
        • 2011-12-03
        相关资源
        最近更新 更多