php - Windows 10 XAMPP 上的 GetText 无法翻译我的文本
问题描述
几个小时以来,GetText 让我发疯,我无法让它工作。
这是我的message.po
文件的内容:
msgid ""
msgstr ""
"Project-Id-Version: TEST\n"
"POT-Creation-Date: 2020-06-13 00:44+0200\n"
"PO-Revision-Date: 2020-06-13 00:53+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: nl_BE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "foo"
msgstr "bar"
msgid "fizz"
msgstr "buzz"
它存储在
./locale/nl_BE/LC_MESSAGES/messages.po
msgfmt
我使用命令将它编译成 .MO 文件。
并尝试使其与以下 PHP 代码一起使用
<?php
putenv('LC_ALL=nl_BE');
setlocale(LC_ALL, 'nl_BE');
bindtextdomain("messages", "./locale");
textdomain("messages");
echo _("foo");
echo _("fizz");
输出 :
>php test.php
foofizz
你得到同样的结果吗?知道为什么它不起作用吗?
不确定它是否相关,但我使用的是 Windows 10。我的 PHP 版本是 PHP 7.2.28(与 XAMPP 一起安装)
此外, phpinfo() 声明 gettext 已启用:
获取文本
GetText 支持 => 启用
任何帮助真的很感激!
解决方案
这是 2009 年已知的 Windows PHP 问题,PHP 团队中似乎没有人关心。
经过一整天的工作,我终于找到了一个我可以忍受的解决方法。
这里或其他地方的答案都没有帮助我,也没有被遗弃的 gettext 替换脚本 - 但它帮助我找到了问题。
我什至更改了 Windows 语言环境 - 没有帮助 - 而且我不想更改我的 Windows 语言,因为我需要在我的网站脚本上调试即时语言更改,并且每次翻译更改都必须重新启动是没有选择的 ;-)
我已经安装了其他语言和本地人,但没有任何帮助。
问题是你可以做你想做的事,但至少我的 WIN10 64pro DID从来没有查看过任何其他文件夹,而不是我的主要 Windows 语言的文件夹
/de_DE/LC_MESSAGES
我删除了与 gettext 的功能无关的任何内容,
这五行仍然作为最小可重现的工作示例。
$path= "C:/xampp/htdocs/locale";
$domain = 'messages';
bindtextdomain($domain, $path);
textdomain($domain);
print _("The string you want to translate" );
所以我的想法是改变这 5 行中的任何内容以显示不同的语言
路径也可以是相对的,例如 realpath('./locale'));
我发现在使用有效的 .mp 文件调用bindtextdomain后,您必须重新启动 APACHE!再次返回默认值,因为显然语言字符串被缓存在任何地方。
所以改变它以获得不同翻译的解决方案不起作用。
所以我研究了第二个参数: $domain 并且测试表明这非常适合我的目的。
将其更改为错误并重新加载原始未翻译文本后显示。将其更改回正确的文本后,立即显示翻译文本。
我感觉很棒
现在我想显示两种以上的语言。
我改名为塞尔维亚西里尔文!pig 示例代码的 .mo 和 .po 文件到 message1.po 和 message1.mo 并将它们移动到
/de_DE/LC_MESSAGES
我现在有 4 个文件
message.mo //german translation compiled
message.po //german translation original
message1.po // serbian cyrillic original
message1.po // serbian cyrillic original
并将第二行设置为“message1”
$domain = 'messages1';
并且显示了西里尔代码!
我没有将西里尔语言加载到我的 Windows 中,没有 serbian local ,什么都没有。只有英语和德语。
这意味着至少在安装了德语的 Windows 10 中,没有必要安装语言或区域设置来使 gettext 正常工作!(我不知道这是否也是真实的中国……但那是另一回事)
因此,如果您有一个远程 Linux 服务器并且想要测试您的国际化,您所要做的就是
1.) 制作所有 messages.po 和 -mo 文件的副本,
将它们全部重命名为所需的名称
例如 messages_de.po /..mo 或 German.po .. 随便你
将所有这些文件放入您安装的 Windows 语言名称的文件夹中
例如 /de_DE/ 或 /en_US/
并将消息变量更改为所需的值
您可能会说“我不想更改我的代码 OM 部署”
然后,您只需在 Apache 中设置一个环境变量,并且仅当脚本在具有环境上下文“dev”的 localhost windows 机器上运行时,然后运行 Windows 解决方法。在您的远程生产系统上,您运行标准的 gettext 初始化。
if (getenv("SERVER_CONTEXT") == "dev")
{
switch (GET('lang')) {
case "de":
$domain="messages_de";
break;
case "fr":
$domain = "messages_fr";
break;
default: //untranslated english texts
$domain = "";
}
$path= "C:/xampp/htdocs/locale";
bindtextdomain($domain, $path);
textdomain($domain);
}
elseif (getenv("SERVER_CONTEXT") == "prod"))
{ the standard gettext initialization for the remote host }
print _("The string you want to translate" );
在您的 Windows 机器上,您的默认语言目录中应该还有以下 4 个文件:
messages_fr.mo
messages_fr.po
messages_de.po
messages_de.po
注意:对于系统的自动检测步骤,您需要两个小的配置更改:
在 Apache 配置中,在 Windows 机器的虚拟主机中设置以下变量:
SetEnv SERVER_CONTEXT "dev"
在远程生产系统的 virthost 的 Apache 配置中:
SetEnv SERVER_CONTEXT "prod"
推荐阅读
- wso2-am - 我可以在序列中介中获取登录的用户角色吗?
- flutter - Dart 语言在 VS 代码中不执行
- c# - RedirectToAction 在 dot net core 3.1 中不起作用
- python - Python中的和弦图
- javascript - React 和 TypeScript:不是箭头函数的功能组件
- c# - 如何使用 c# winforms 在 Printdialog Control 中打印 PDF 文档
- python - 额外的未识别文本与子图标题冲突
- flutter - 如何将小部件放在可拖动的位置?
- spring-boot - 我们可以在弹簧靴中做没有轴突的 CQRS
- react-native - React Native 调试:console.logs 正在重复