管理共享托管上的getText翻译
核心要点
- Gettext是PHP网站翻译管理的流行方法,但它有一个显着缺点:Apache缓存翻译,这意味着除非重新启动引擎,否则翻译文件的更新将不可见。这在共享主机上尤其成问题,因为通常无法获得管理员权限。
- Audero Shared Gettext是一个PHP库,允许开发者绕过Apache对通过gettext()函数加载的翻译的缓存。该库使用一个简单的技巧,创建翻译文件的镜像副本,从而欺骗Apache将其视为新的、不相关的翻译,从而避免缓存问题。
- Audero Shared Gettext可以通过Composer、Git或从存储库下载存档来安装。安装后,开发者可以使用Composer的自动加载器动态加载类并创建SharedGettext实例。
- 该库由于使用了命名空间,因此需要PHP 5.3或更高版本,并根据CC BY-NC 4.0许可证发布,可以免费使用。它的两个主要方法是updateTranslation(),它创建翻译文件的镜像副本,以及deleteOldTranslations(),它删除选定翻译文件夹中除最新镜像副本以外的所有副本。
许多公司最终都会将目标市场转向全球。这一目标将带来将公司网站翻译成一种或多种语言的需求。即使您不为大公司工作,您也可能需要以您的母语(假设您不是英语母语人士)推出新服务以瞄准当地市场,并以英语面向全球市场。作为开发者,我们的职责不是翻译文本,而是准备网站以支持翻译。在PHP中,最流行的方法是通过Gettext。这是一种很棒的方法,因为它允许将翻译与应用程序分离,从而实现流程的并行化。问题在于,Apache缓存翻译,因此,除非您可以重新启动引擎,否则翻译文件的任何更新都将不会显示。如果您在共享主机上工作并且没有管理员权限,那么这一事实尤其令人恼火。在本文中,我将详细描述此问题并解释我找到的解决方案以避免此问题。
注意:如果您不熟悉I18N、翻译和Gettext的概念,我强烈建议您在进一步探索本文之前阅读本系列文章。它将为您提供比您在此处找到的简要概述更详细的信息,并帮助您更好地理解这些主题。
环境设置
在PHP中使用翻译有很多方法。我能回忆起的最简单的一种方法是拥有一个包含所有翻译字符串的关联数组,然后使用键来检索正确的字符串。正如您可能猜到的那样,此解决方案的扩展性不佳,除非您正在处理一个非常非常小的项目(也许不超过5行代码),否则应避免使用此解决方案。对于严肃的翻译,我们可以使用Gettext。这种方法使我们能够为每个目标语言拥有不同的文件,这有助于维护业务逻辑、表示层和翻译(我们可以将其视为表示层的附加组件)之间的分离。使用Gettext,我们可以并行化流程,因为在我们处理网站的某些功能时,翻译人员仍然可以使用Poedit等软件进行翻译。
翻译应存储在具有固定结构的路径中。首先,我们将有一个根据您的喜好命名的根文件夹(例如“languages”)。在其中,我们必须为每个目标语言创建一个文件夹,其名称必须符合ISO 3166标准。因此,意大利语翻译的有效名称可以是“it_IT”(意大利语意大利语)、“it_CH”(意大利语瑞士语)、“en_US”(美国英语)等等。在具有语言代码的文件夹中,我们必须有一个名为“LC_MESSAGES”的文件夹,最后,我们将在其中存储翻译文件。
Poedit分析网站的源代码,根据我们在软件中设置的一种或多种模式提取要翻译的字符串。它将字符串保存在扩展名为.po(Portable Object)的单个文件中,该软件(或等效软件)会将其编译成二进制.mo文件。后者是我们和PHP的gettext()函数感兴趣的格式。.mo文件是我们必须放置在我们之前创建的“LC_MESSAGES”目录中的文件。
使用gettext()的示例代码如下(代码已添加注释,以便您快速了解其作用):
<?php // 包含翻译文件的根文件夹的名称 $translationsPath = 'languages'; // 要翻译到的语言 $language = 'it_IT'; // 翻译文件的名称(在gettext中称为域) $domain = 'audero'; // 指示此会话将使用哪种语言 putenv("LANG=" . $language); setlocale(LC_ALL, $language); // 设置当前域的路径 bindtextdomain($domain, $translationsPath); // 指定字符编码 bind_textdomain_codeset($domain, 'UTF-8'); // 选择域 textdomain($domain); // 调用gettext()函数(它有一个名为_()的别名) echo gettext("HELLO_WORLD"); // 等效于echo _("HELLO_WORLD"); ?>
将之前的代码保存在页面中并在浏览器中加载后,如果gettext()能够找到翻译文件,您将在屏幕上看到您进行的翻译。
到目前为止,一切顺利。坏消息是,一旦加载翻译,Apache就会对其进行缓存。因此,除非我们可以重新启动引擎,否则翻译文件的任何更新都将不会显示。如果我们在共享主机上工作并且没有管理员权限,那么这尤其令人恼火。如何解决此问题?Audero Shared Gettext来救援!
什么是Audero Shared Gettext
Audero Shared Gettext是一个PHP库(实际上只是一个类,但让我做梦吧),它允许您绕过通过gettext()函数加载的翻译被Apache缓存的问题。该库采用了一种简单而有效的方法,因此您将始终使用最新的翻译。Audero Shared Gettext需要PHP 5.3或更高版本,因为它使用命名空间,并且存在上一节中描述的结构。它有两个主要方法:updateTranslation()和deleteOldTranslations()。前者是库的核心,也是实现此技巧的方法。但是这个技巧是什么呢?让我们看看它的代码,以了解更多信息。为了充分理解它,值得强调的是,类的构造函数接受存储翻译的路径、要翻译到的语言以及翻译文件的名称(域)。
<?php // 包含翻译文件的根文件夹的名称 $translationsPath = 'languages'; // 要翻译到的语言 $language = 'it_IT'; // 翻译文件的名称(在gettext中称为域) $domain = 'audero'; // 指示此会话将使用哪种语言 putenv("LANG=" . $language); setlocale(LC_ALL, $language); // 设置当前域的路径 bindtextdomain($domain, $translationsPath); // 指定字符编码 bind_textdomain_codeset($domain, 'UTF-8'); // 选择域 textdomain($domain); // 调用gettext()函数(它有一个名为_()的别名) echo gettext("HELLO_WORLD"); // 等效于echo _("HELLO_WORLD"); ?>
该方法首先要做的是测试原始的二进制翻译文件(.mo文件)是否存在。如果不存在,则该方法会引发异常。然后,它根据提供给构造函数的参数和文件的最后修改时间戳计算翻译文件的完整路径。之后,它创建一个新的字符串,将原始域与之前计算的时间戳连接起来。完成后,这里就是技巧所在,它会创建翻译文件的镜像副本。如果已经存在具有此类名称的文件,则该类足够智能以避免此复制。最后,它返回将在bindtextdomain()、bind_textdomain_codeset()和textdomain()中使用的新名称。这样做,Apache将看到翻译就像它与原始翻译无关一样,从而避免了缓存问题。正如我所说,简单而有效!
“伟大的Aurelio!”,你在想,“但是这样我的文件夹就会因为这些复制而膨胀。”没错。这就是我创建deleteOldTranslations()的原因。它删除了选定翻译文件夹中除最后一个以外的所有镜像副本。
现在您已经了解了Audero Shared Gettext是什么以及它可以为您做什么,让我们看看如何获得它。
安装Audero Shared Gettext
您可以通过Composer获得“Audero Shared Gettext”,将以下几行添加到您的composer.json中:
/** * 创建翻译文件的镜像副本 * * @return string 创建的翻译文件的名称(在gettext中称为域) * * @throws \Exception 如果找不到翻译文件 */ public function updateTranslation() { if (!self::translationExists()) { throw new \Exception('在给定路径中找不到翻译文件。'); } $originalTranslationPath = $this->getTranslationPath(); $lastAccess = filemtime($originalTranslationPath); $newTranslationPath = str_replace(self::FILE_EXTENSION, $lastAccess . self::FILE_EXTENSION, $originalTranslationPath); if(!file_exists($newTranslationPath)) { copy($originalTranslationPath, $newTranslationPath); } return $this->domain . $lastAccess; }
然后运行安装命令以解析和下载依赖项:
"require": { "audero/audero-shared-gettext": "1.0.*" }
Composer会将库安装到您项目的vendor/audero目录中。
如果您不想使用Composer(您真的应该这样做),您可以通过运行以下命令来通过Git获得Audero Shared Gettext:
php composer.phar install
您拥有的最后一个选项是访问存储库并将其下载为存档。
如何使用Audero Shared Gettext
假设您使用Composer获得了Audero Shared Gettext,您可以依靠其自动加载器来动态加载该类。然后,您必须创建一个SharedGettext实例并调用您需要的 method。您可以使用前面提到的方法之一,如下例所示。
git clone https://github.com/AurelioDeRosa/Audero-Shared-Gettext.git
结论
本文向您介绍了Audero Shared Gettext,这是一个简单的库(嗯……类),它允许您绕过通过gettext()函数加载的翻译被Apache缓存的问题。Audero Shared Gettext具有广泛的兼容性,因为它要求您至少拥有PHP 5.3(已经发布一段时间了),因为它使用了命名空间。随意使用存储库中包含的演示和文件,如果您发现问题,请提交Pull Request和问题。我已经根据CC BY-NC 4.0许可证发布了Audero Shared Gettext,因此可以免费使用。
您是否遇到过此问题?您是如何解决的?不要害羞,在评论中发布您的解决方案!
(以下为FAQ部分,已根据原文进行伪原创,并保持原文大意)
关于在共享主机上管理Gettext翻译的常见问题解答 (FAQ)
如何在我的共享主机上安装Gettext?
在共享主机上安装Gettext可能有点棘手,因为您可能没有root访问权限。但是,您仍然可以通过cPanel或Plesk安装它。在cPanel中,您可以在“选择PHP版本”部分下找到启用Gettext的选项。在Plesk中,您可以在“PHP设置”部分下启用它。如果您找不到这些选项,您可能需要联系您的主机提供商寻求帮助。
为什么我的Gettext翻译不起作用?
您的Gettext翻译不起作用可能有几个原因。一个常见的问题是.mo文件没有正确编译或文件路径不正确。确保.mo文件位于正确的目录中,并且代码中的文件路径正确。另一个问题可能是您使用的区域设置不受服务器支持。您可以使用locale -a命令检查这一点。
如何调试Gettext翻译?
调试Gettext翻译可以通过检查.po和.mo文件中的错误来完成。您可以使用Poedit等工具打开这些文件并检查是否存在任何语法错误。此外,您可以在代码中使用gettext函数来检查翻译是否正在正确获取。如果该函数返回原始字符串,则表示找不到翻译。
我可以在WordPress中使用Gettext吗?
是的,您可以在WordPress中使用Gettext。WordPress使用Gettext作为其本地化框架。您可以在WordPress中使用__()和_e()函数来获取翻译。这些函数在后台使用Gettext。
如何更新我的Gettext翻译?
您可以通过更新.po文件然后将其编译成.mo文件来更新您的Gettext翻译。.po文件是一个纯文本文件,您可以使用任何文本编辑器打开它。完成更改后,您可以使用Poedit之类的工具将.po文件编译成.mo文件。
为什么我会收到“无法找到软件包php-gettext”错误?
此错误通常发生在您的服务器正在使用的存储库中没有该软件包时。您可以尝试使用sudo apt-get update命令更新您的软件包列表。如果错误仍然存在,您可能需要添加其他存储库或手动安装软件包。
如何在PHP中使用Gettext?
您可以通过使用gettext函数在PHP中使用Gettext。此函数将字符串作为参数,并返回翻译后的字符串。在您可以使用此函数之前,您需要使用setlocale函数设置区域设置,并使用bindtextdomain函数指定.mo文件的路径。
我可以在Ubuntu上使用Gettext吗?
是的,您可以在Ubuntu上使用Gettext。您可以使用sudo apt-get install gettext命令安装它。安装后,您可以使用终端中的gettext命令来处理.po和.mo文件。
如何创建.po和.mo文件?
您可以使用Poedit之类的工具创建.po和.mo文件。此工具允许您创建和编辑.po文件并自动将其编译成.mo文件。您也可以使用文本编辑器手动创建.po文件,但是您需要Poedit或msgfmt之类的工具才能将其编译成.mo文件。
.po和.mo文件有什么区别?
.po文件是包含原始字符串及其翻译的纯文本文件。它们可以使用任何文本编辑器打开和编辑。另一方面,.mo文件是根据.po文件生成的二进制文件。它们在运行时由Gettext用于获取翻译。
以上是管理共享托管上的getText翻译的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

会话劫持可以通过以下步骤实现:1.获取会话ID,2.使用会话ID,3.保持会话活跃。在PHP中防范会话劫持的方法包括:1.使用session_regenerate_id()函数重新生成会话ID,2.通过数据库存储会话数据,3.确保所有会话数据通过HTTPS传输。

PHP8.1中的枚举功能通过定义命名常量增强了代码的清晰度和类型安全性。1)枚举可以是整数、字符串或对象,提高了代码可读性和类型安全性。2)枚举基于类,支持面向对象特性,如遍历和反射。3)枚举可用于比较和赋值,确保类型安全。4)枚举支持添加方法,实现复杂逻辑。5)严格类型检查和错误处理可避免常见错误。6)枚举减少魔法值,提升可维护性,但需注意性能优化。

SOLID原则在PHP开发中的应用包括:1.单一职责原则(SRP):每个类只负责一个功能。2.开闭原则(OCP):通过扩展而非修改实现变化。3.里氏替换原则(LSP):子类可替换基类而不影响程序正确性。4.接口隔离原则(ISP):使用细粒度接口避免依赖不使用的方法。5.依赖倒置原则(DIP):高低层次模块都依赖于抽象,通过依赖注入实现。

在PHPStorm中如何进行CLI模式的调试?在使用PHPStorm进行开发时,有时我们需要在命令行界面(CLI)模式下调试PHP�...

使用PHP的cURL库发送JSON数据在PHP开发中,经常需要与外部API进行交互,其中一种常见的方式是使用cURL库发送POST�...

如何在系统重启后自动设置unixsocket的权限每次系统重启后,我们都需要执行以下命令来修改unixsocket的权限:sudo...
