php 如何制作多语言网站

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2487171/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 06:40:24  来源:igfitidea点击:

How to make a Multilanguage website

phpmysqlinternationalizationmultilingual

提问by user295239

Can any body tell me how to make a dynamic multilanguage website in PHP and MySQL? I have no idea about it. I searched on Google and didn't find any good solutions.

任何人都可以告诉我如何在 PHP 和 MySQL 中制作动态多语言网站吗?我不知道。我在谷歌上搜索并没有找到任何好的解决方案。

Can any one provide me with a step by step guide? If possible make a demo for a multilanguage website. Or please refer me to any link where it explains the details about it.

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

回答by Edurne Pascual

Short answer:there is no short answer, as there are a lot of variables to consider, and plenty of work to do. So...

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

Long answer:I'm going to break it down as well as I can, but there isn't a "good for all" answer to a question as broad as yours.

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

First, variables of the task at hand:

首先,手头任务的变量:

  1. List of languages: will your site be in a predefined set of languages, or will it be varied/heterogeneous? For example, a site may be entirely bilingual in two well defined languages (or, to put another example, I run an English/Catalan/Spanish site); or different sections could be available on different sets of languages (for an example, look at MS's sites: they are mostly homogeneous, but stuff like blogs, KB articles, and some docs are just available in a subset of the supposedly supported languages).

  2. Translations source: is content provided in each relevant language by you or some collaborator? Or are some versions run through translation software from a single "base" language? The first approach takes a lot of extra work to produce the contents, but yields higher quality results than the second.

  3. Languages themselves: once you have 1) and 2) answered, you will need to be aware of exactly which languages are you working with. Note that in the case you include dialects (ex: US English + UK English, or Argentina Spanish + Spain Spanish), you may encounter some "duplicate content" issues with search engines, but details on that are too off-topic here (just mentioning so you are aware of the potential issues).

  4. Are you targeting languages in the abstract (for example, my site offers the three languages without caring at all where the visitor is: that's what I have, so choose what you prefer); or rather targeting different regions/countries? In the later case, things can get extra complex, as you may need to care about other stuff besides languages (like timezones, currencies, or date-time format conventions, to name some), but you get the benefit of being able to use country-specific TLDs.

  1. 语言列表:您的网站将使用一组预定义的语言,还是多种多样/异类?例如,一个站点可能完全是双语的,有两种定义明确的语言(或者,再举一个例子,我运行一个英语/加泰罗尼亚语/西班牙语站点);或者不同的部分可以在不同的语言集上使用(例如,查看 MS 的站点:它们大多是同质的,但是像博客、知识库文章和一些文档之类的东西只以假定支持的语言的子集提供)。

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

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

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

Once you have the above well-defined, let's start working. These are the most prominent tasks you'd need to do handle:

一旦你有了上述明确定义,让我们开始工作。这些是您需要处理的最重要的任务:

  1. Language detection: the most reasonable approach is to use a GET parameter (something like ?lang=en-us on the URL). Also, you might use some cookie and/or IP geolocation to fall back when a URL with no language argument is requested. Also, if you have the means, consider the topic of URL beautification (what looks better: example.com/index.php?lang=en-usor example.com/en-us/home?). Personally, I love the power ModRewrite grants to my .htaccess file, but that'll only work on Apache-powered servers.

  2. Content management: regardless of whether you are fetching content from a DB (like article content), include files (typical for breadcrumbs, menus, site-wide headings, etc), or any other means, you will need some way to separate each version (language) of the content. Here are some examples of how it can be done:

    • For DB content, my best advise is to come up with some solid field naming pattern and stick to it. For example, I append _en, _es, or _cato all language-dependent fields of my DB. This way, I can access the right content with expressions like $row["title_$lang"].
    • For include files, again a file naming convention is the sanest approach. In my case, I have file names ending with .en.php, .ca.htm, etc. My include calls then look like include("some-filename.$lang.php).
    • From time to time, you will be spitting out small chunks of text directly from your PHP code (for example, when labeling the headings of a table). You can use an include file per language defining a "chunks" array with the same keys, or a DB table like Geert suggested. The former approach takes less work to develop, the latter should take less work to maintain (especially if you aren't working alone).
  3. Language pick: quite essential, you should provide your users a way to choose their own language, other than tweaking the GET arguments on the URL itself. For few languages, "flags" often work great, since they can be understood even if the page has initially fallen back to a language the user doesn't know at all. For more languages, a dropdown menu seems more efficient (in terms of viewport space), but you should make sure to add some visual (ie: non-textual) hints. Some sites force you to pick a language upon entering, and only have links to the home-page on each language. Personally, I have my three flags standing out on top of my site's menu, each pointing to the current address with only the language argument changed. A code like this can work quite well:

  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. 内容管理:无论您是从数据库中获取内容(如文章内容)、包含文件(典型的面包屑、菜单、站点范围的标题等),还是任何其他方式,您都需要某种方式来分隔每个版本(语言)内容。以下是如何完成的一些示例:

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



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


  1. CMS tweaking: if your site (or part of it) is using some kind of CMS, discussion board, etc, things can get quite messy. Speaking from my own experience, I have a phpBB forum on my site split in three main categories (one per language), in such a way that they look like three independent forums (but users just need to login/register on one of them to gain access to all languages, since they are indeed just categories of the same board). The tweaks I had to make for this to work smoothly threatened the last remnants of sanity I still keep :S. For these cases, I advise looking up the docs and support features of the specific software you are using.
  1. CMS 调整:如果您的网站(或其中的一部分)正在使用某种 CMS、讨论板等,事情会变得非常混乱。根据我自己的经验,我的网站上有一个 phpBB 论坛,分为三个主要类别(每种语言一个),这样它们看起来就像三个独立的论坛(但用户只需要在其中一个上登录/注册即可获得所有语言的访问权限,因为它们确实只是同一个板的类别)。我必须进行的调整才能顺利进行,这威胁到了我仍然保留的最后一丝理智:S。对于这些情况,我建议查找您正在使用的特定软件的文档和支持功能。

Well, that's everything I can come out with for now. I think you should have enough to pull up your sleeves and get to work. Then, if you hit some wall on your path, come back with specific questions and I'm confident you'll get more specific answers.

嗯,这就是我现在能想到的一切。我认为你应该有足够的钱来挽起袖子开始工作。然后,如果您在路上遇到了障碍,请带着具体问题回来,我相信您会得到更具体的答案。

Hope this helps.

希望这可以帮助。

回答by Geert

The solution I always use is to create a database table, with all possible messages. For each message I use a code (abbreviation) to look it up. So for example:

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

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?

etc. Looking up the translations is usually fast enough by using a MySQL query, but you can also place all messages in a array and load it into memory when your script loads. Users should always be able to set the language they prefer, don't rely blindly on the language header set by the web browser.

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

回答by JoanComasFdz

I am now designing a very tiny CMS that must be multilanguage.

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

One of the features that mosts concerns to me, is that the client can spontaneously decide to add or remove a language.

我最关心的一个特点是,客户可以自发地决定添加或删除一种语言。

For this reason, I am not aiming the design adding suffixes to the database tables, I can not (and want not) to modify the table names or access them using dinamic names, nor adding or removing fields each time a language is defined or removed.

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

I would not use files either, just because I like databases and they are easy to mantain.

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

And lastly, I think in two types of translation:

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

  1. The web text.
  2. The content text.
  1. 网络文字。
  2. 内容文本。

Therefore, my design aims to:

因此,我的设计旨在:

  • languajesA table with the languages defined.
  • translationsA single table that will have all the messages, as follows:
    • [pk] table_namethe name of the table which content will be translated.
    • [pk] field_namethe name of the field which content will be translated.
    • [pk] row_idthe row identificator for the item that will be translated.
    • [pk] languagethe language that the text is translated.
    • textthe translated text.
  • languajes定义了语言的表。
  • 翻译用一个表格将所有的信息,如下所示:
    • [pk] table_name内容将被翻译的表的名称。
    • [pk] field_name内容将被翻译的字段的名称。
    • [pk] row_id将被翻译的项目的行标识符。
    • [pk]语言文本翻译的语言。
    • text翻译的文本。

That means that the tables which fields will have content in a single-language scenario, now will have its content void, because it will always be in the translations table.

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

That will increase the sql querys complexity, but it allows me to develop tools to maintain the translations in an easy way. Also, the complexity of the sql will exist only once, just when implementing the solution. If that implementation is properly designed, the maintenance / extensibility of the site doesn't have to be a major problem.

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

Edit:

编辑

After some conversation with developer friends, I think that the solution i am aproaching here has too much charge on a single table.

在与开发人员朋友交谈后,我认为我在这里提出的解决方案在一张桌子上收费太多。

Another approach that I will study from now on is creating an extra table for each "translatable table" as follows:

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

  • any_translatable_table: The table which need to translate any of its fields
  • any_translatable_table_translations: The table where the translations will be stored.
    • [pk] field_namethe name of the field which content will be translated.
    • [pk] row_idthe row identificator for the item that will be translated.
    • [pk] languagethe language that the text is translated.
    • textthe translated text.
  • any_translatable_table:需要翻译任何字段的表
  • any_translatable_table_translations:存储翻译的表。
    • [pk] field_name内容将被翻译的字段的名称。
    • [pk] row_id将被翻译的项目的行标识符。
    • [pk]语言文本翻译的语言。
    • text翻译的文本。

This scheme inherits the concepts from the first one, but separates it's content per tables. This alternative solution may increase the performance and isolate the problems (as indexes problems).

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

The extra translation table per "translatable table" will be created at the same time that the original one.

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

And about the sql querys, the complexity is still the same: The first approach needs the table name to search into translations table, but the second just adds the suffix "_translations" at the table name.

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