【问题标题】:How to make a Multilanguage website [closed]如何制作多语言网站[关闭]
【发布时间】:2011-01-30 00:56:20
【问题描述】:

谁能告诉我如何用 PHP 和 MySQL 制作动态多语言网站?我对此一无所知。我在谷歌上搜索并没有找到任何好的解决方案。

任何人都可以为我提供分步指南吗?如果可能,为多语言网站制作演示。或者请参考任何链接,其中解释了有关它的详细信息。

【问题讨论】:

    标签: php mysql internationalization multilingual


    【解决方案1】:

    简答:没有简答,因为有很多变量需要考虑,还有很多工作要做。所以……

    长答案:我将尽我所能分解它,但对于像你这样广泛的问题,没有一个“对所有人都有好处”的答案。

    首先,手头任务的变量:

    1. 语言列表:您的网站会使用预定义的语言集,还是会变化/异类?例如,一个网站可能完全是两种定义明确的语言的双语(或者,再举一个例子,我经营一个英语/加泰罗尼亚语/西班牙语网站);或者可以在不同的语言集上提供不同的部分(例如,查看 MS 的网站:它们大多是同质的,但博客、知识库文章和某些文档等内容仅以所谓的支持语言的子集提供)。

    2. 翻译来源:每种相关语言的内容是由您还是某个合作者提供的?还是某些版本通过翻译软件从单一“基础”语言运行?第一种方法需要大量额外的工作来生成内容,但比第二种方法产生的结果质量更高。

    3. 语言本身:一旦您回答了 1) 和 2),您将需要确切了解您正在使用哪些语言。请注意,如果您包含方言(例如:美国英语 + 英国英语,或阿根廷西班牙语 + 西班牙西班牙语),您可能会在搜索引擎中遇到一些“重复内容”问题,但这里的详细信息太离题了(只是提及以便您了解潜在问题)。

    4. 您是否针对抽象语言(例如,我的网站提供三种语言而完全不关心访问者在哪里:这就是我所拥有的,所以选择您喜欢的语言);还是针对不同的地区/国家?在后一种情况下,事情可能会变得更加复杂,因为您可能需要关心除语言之外的其他内容(例如时区、货币或日期时间格式约定等),但您可以获得能够使用的好处特定国家/地区的 TLD。

    一旦您对上述内容进行了明确定义,就可以开始工作了。这些是您需要处理的最突出的任务:

    1. 语言检测:最合理的方法是使用 GET 参数(类似于 URL 上的 ?lang=en-us)。此外,当请求没有语言参数的 URL 时,您可能会使用一些 cookie 和/或 IP 地理位置来回退。另外,如果你有办法,可以考虑 URL 美化这个话题(哪个更好看:example.com/index.php?lang=en-usexample.com/en-us/home?)。就我个人而言,我喜欢 ModRewrite 授予我的 .htaccess 文件的功能,但这仅适用于 Apache 驱动的服务器。

    2. 内容管理:无论您是从数据库中获取内容(如文章内容)、包含文件(通常用于面包屑、菜单、站点范围的标题等),还是任何其他方式,您都需要一些方法来将内容的每个版本(语言)分开。以下是一些如何实现的示例:

      • 对于 DB 内容,我最好的建议是提出一些可靠的字段命名模式并坚持下去。例如,我将_en_es_ca 附加到我的数据库的所有语言相关字段。这样,我可以使用$row["title_$lang"] 等表达式访问正确的内容。
      • 对于包含文件,文件命名约定也是最明智的方法。就我而言,我的文件名以.en.php.ca.htm 等结尾。我的包含调用看起来像include("some-filename.$lang.php)
      • 有时,您会直接从 PHP 代码中吐出一小段文本(例如,在为表格标题添加标签时)。您可以使用每种语言的包含文件来定义具有相同键的“块”数组,或者像 Geert 建议的数据库表。前一种方法需要较少的开发工作,后者应该需要较少的维护工作(尤其是在您不单独工作时)。
    3. 语言选择:非常重要,除了调整 URL 本身的 GET 参数之外,您应该为用户提供一种选择自己语言的方法。对于少数语言,“标志”通常效果很好,因为即使页面最初退回到用户根本不知道的语言,它们也可以被理解。对于更多语言,下拉菜单似乎更有效(就视口空间而言),但您应该确保添加一些视觉(即:非文本)提示。有些网站会强制您在输入时选择一种语言,并且每种语言只有指向主页的链接。就我个人而言,我的三个标志位于站点菜单的顶部,每个都指向当前地址,只更改了语言参数。像这样的代码可以很好地工作:


    function translatedURI($new_lang) {
        return str_replace("lang=$lang", "lang=$new_lang", "http://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
    }
    

    1. CMS 调整:如果您的网站(或其中的一部分)使用某种 CMS、讨论板等,事情会变得非常混乱。根据我自己的经验,我的网站上有一个 phpBB 论坛,分为三个主要类别(每种语言一个),它们看起来像三个独立的论坛(但用户只需要在其中一个上登录/注册即可获得所有语言的访问权限,因为它们确实只是同一板的类别)。我必须进行的调整才能使其顺利运行,这威胁到我仍然保留的最后一丝理智:S。对于这些情况,我建议您查找您正在使用的特定软件的文档和支持功能。

    嗯,这就是我现在能想到的一切。我认为你应该有足够的时间挽起袖子开始工作。然后,如果您在前进的道路上碰壁,请回来提出具体问题,我相信您会得到更具体的答案。

    希望这会有所帮助。

    【讨论】:

    • 很棒的信息,非常感谢您抽出宝贵的时间来编写它。
    • 优秀的答案!谢谢你:)
    【解决方案2】:

    我一直使用的解决方案是创建一个包含所有可能消息的数据库表。对于每条消息,我使用一个代码(缩写)来查找它。比如:

    lang  id        message
    en    login     Login
    en    lostpass  Lost your password?
    de    login     Anmelden
    de    lostpass  Paswort vergessen?
    nl    login     Aanmelden
    nl    lostpass  Wachtwoord vergeten?
    

    等等。使用 MySQL 查询查找翻译通常足够快,但您也可以将所有消息放在一个数组中,并在脚本加载时将其加载到内存中。用户应该始终能够设置他们喜欢的语言,不要盲目依赖网络浏览器设置的语言头。

    【讨论】:

    • 我的问题(为什么你没有得到赞成票)是一个页面可能有 100 多个 SQL 查找。即使您将它们存储在内存缓存(memcached)中,SQL 查找仍然存在。正确/有效的解决方案是创建一个本地化类,该类将对填充有翻译数组的静态文件(en_us.php、en_gb.php 等)执行查找。尽管您提到了类似的事情,但我仍然不喜欢您仍然为此建议/依赖 SQL 的事实。
    • 文件解析与数据库访问——永恒的讨论。如果您运行的是自制服务器,文件是最好的解决方案,但如果您使用专业的高性能服务器,则数据库访问时间和开销变得无关紧要。文件用于 SMALL,DB 用于 PRO。谢谢@geert!
    • 如果ID为“title”的字符串需要在每个页面上都不同怎么办?将“文件”列添加到数据库。然后,在每一页上运行SELECT * FROM ... WHERE file = 'filename.php'。循环遍历每个结果行,然后将翻译添加到常量或数组,或者您正在处理的语言。这也将阻止“100 多个 SQL 查找的可能性”。
    【解决方案3】:

    我现在正在设计一个非常小的 CMS,它必须是多语言的。

    我最关心的功能之一是客户可以自发地决定添加或删除一种语言。

    出于这个原因,我的目标不是为数据库表添加后缀,我不能(也不想)修改表名或使用动态名称访问它们,也不能在每次使用语言时添加或删除字段定义或删除。

    我也不会使用文件,只是因为我喜欢数据库并且它们易于维护。

    最后,我认为有两种翻译:

    1. 网络文本。
    2. 内容文本。

    因此,我的设计旨在:

    • languages 包含已定义语言的表格。
    • translations 包含所有消息的单个表,如下所示:
    • [pk] table_name要翻译内容的表格的名称。
    • [pk] field_name要翻译内容的字段名称。
    • [pk] row_id 要翻译的项目的行标识符。
    • [pk] 语言文本翻译的语言。
    • 文本翻译的文本。

    这意味着在单语言场景中哪些字段将具有内容的表现在将其内容无效,因为它将始终在翻译表中。

    这会增加 SQL 查询的复杂性,但它允许我开发工具来以简单的方式维护翻译。此外,SQL 的复杂性只存在一次,就在实施解决方案时。如果该实施设计得当,网站的维护/可扩展性就不会成为主要问题。

    编辑

    在与开发者朋友交谈后,我认为我在这里接近的解决方案在单张桌子上收费过高。

    我将从现在开始研究的另一种方法是为每个“可翻译表”创建一个额外的表,如下所示:

    • any_translatable_table:需要翻译其任何字段的表
    • any_translatable_table_translations:将存储翻译的表。
    • [pk] field_name要翻译内容的字段名称。
    • [pk] row_id 要翻译的项目的行标识符。
    • [pk] 语言文本翻译的语言。
    • 文本翻译的文本。

    此方案继承了第一个方案的概念,但将每个表格的内容分开。这种替代解决方案可能会提高性能并隔离问题(作为索引问题)。

    每个“可翻译表”的额外翻译表将与原始翻译表同时创建。

    关于SQL查询,复杂度还是一样的:第一种方法需要表名来搜索translations表,而第二种方法只是在表名后面加上后缀“_translations”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-14
      • 2016-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多