Multi language PHP application: best practice?

2019-04-08 11:53发布

问题:

I'd like to get your feedback over the way I implemented multi-language support on my PHP MVC web app. That's how I did:

  • in the /app folder I created a /languages folder which contains one file per language (english.php, spanish.php, etc.)
  • each file contains a serie of variables with the same names in each files, containing the texts to render in the views
  • these variables are then echoed in the different views
  • a "language" cookie variable is updated when the user changes the language
  • in the controller of each view, I include a language file on the following format:

include $_SERVER['DOCUMENT_ROOT'] . "/app/languages/" . $_COOKIE["language"] . ".php";

Sounds pretty neat to me. Would you have any negative thoughts about this method?

回答1:

As you're on PHP 5.3.2 I'd definitely recommend checking out the intl extension if you can. It's full of handy functions and classes to assist in i18n. For instance you can use the following snippet to generate a "best-fit" language for your visitor from those you have available:

$langs = array('en', 'fr', 'de');
$preferences = Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);
$locale = Locale::lookup($langs, $preferences);

There's also a lot more to think about than straight word-for-word replacements. Different languages have different formatting conventions. There's a lot of information in this Zend article that might prove useful.

My code uses XSL for templating so personally, when it comes to translations I use XML language files and XPath queries so that the language file can be understood directly by templates but is also available to PHP for formatting strings with MessageFormatter.

I'd avoid using the database as a store to be honest, simply for performance.



回答2:

You could also parse the accept-language header to help decide what do do.

Accept-Language:en-GB,en-US;q=0.8,en;q=0.6

Mine looks like that. It's not fool proof, but it could be a way to set the appropriate cookie automatically.



回答3:

just some thoughts

  • If you have one file per language and your site has more than a few pages you will quickly loose track of which tag holds which text on which page
  • How do you ensure that when you create a new tag that there are tags in all the other languages and that they are translated?
  • how do you handle formatting for different languages? Romance languages tend to be about 30% longer than English so can screw up the page flow.
  • In the same vein what about Hebrew which is right to left (RTL) not LTR as with european language? Or Chinese and Japanese with potentially different line flows and no white space?
  • How do you do the translations? Export the files and import them again? Do you intend to use xliff or a version of TMX or gettext to make the translators life easier and translation costs cheaper?
  • How do you QA the translations?


回答4:

As you are just having data in the language files, I would recommend using GetText. It is a port of the standard GetText of C++ for internationalization, there are tons of tools to build up the language files and is very fast due to compiled files during runtime.

You essentially build up your data-files (e.g. fr.po, en.po) with a kind-of INI-file format and compile those files to specialized .mo-files (fr.mo, en.mo, ...) and simply echo the internationalized strings with the static function _(), e.g. echo _("Hello World"); would produce the german output Hallo Welt or (if no translation is available in the .mo-files) the default string Hello World.

As for choosing the right language: that depends on your requirements. As already pointed out, you should use the Accept-language-Header of the browser and might want to add support for an overwrite through session-information.