PHP simple translation approach - your opinion PHP simple translation approach - your opinion php php

PHP simple translation approach - your opinion


It does not look bad. I've seen this used many times.

I would however separate the different strings in one file per language. At least, or if the files get large, one file per module per language.

Then your translation class can load and cache the language files (if you don't rely on any other caching system) every time a new language is to be used.

A little example of what i mean

class Translator {    private $lang = array();    private function findString($str,$lang) {        if (array_key_exists($str, $this->lang[$lang])) {            return $this->lang[$lang][$str];        }        return $str;    }    private function splitStrings($str) {        return explode('=',trim($str));    }    public function __($str,$lang) {        if (!array_key_exists($lang, $this->lang)) {            if (file_exists($lang.'.txt')) {                $strings = array_map(array($this,'splitStrings'),file($lang.'.txt'));                foreach ($strings as $k => $v) {                    $this->lang[$lang][$v[0]] = $v[1];                }                return $this->findString($str, $lang);            }            else {                return $str;            }        }        else {            return $this->findString($str, $lang);        }    }}

This will look for .txt files named after the language having entries such as this

Foo=FOO
Bar=BAR

It always falls back to the original string in case it does not find any translation.

It's a very simple example. But there is nothing wrong in my opinion with doing this by yourself if you have no need for a bigger framework.

To use it in a much simpler way you can always do this and create a file called 'EN_Example.txt'

class Example extends Translator {    private $lang = 'EN';    private $package = 'Example';    public function __($str) {        return parent::__($str, $this->lang . '_' . $this->package);    }}

Sometimes you wish to translate strings that contain variables. One such approach is this which i find simple enough to use from time to time.

// Translate string "Fox=FOX %s %s"$e = new Example();// Translated string with substituted arguments$s = printf($e->__('Fox'),'arg 1','arg 2');

To further integrate variable substitution the printf functionality can be put inside the __() function like this

public function __() {    if (func_num_args() < 1) {        return false;    }    $args = func_get_args();    $str = array_shift($args);    if (count($args)) {        return vsprintf(parent::__($str, $this->lang . '_' . $this->package),$args);    }    else {        return parent::__($str, $this->lang . '_' . $this->package);    }}


There are a few things it appears you haven't considered:

  • Are you simply translating single words? What about sentence structure and syntax that differs between languages?
  • What do you do when a word or sentence hasn't been translated into a language yet?
  • Does your translations support variables? The order of words in a sentence can differ in different languages, and if you have a variable it usually won't be good enough simply to split the word around the sentence.

There are a two solutions that I've used and would recommend for PHP:

  • gettext - well supported in multiple languages
  • intsmarty - based on Smarty templates


The advantage with using a class or functions for this is that you can change the storage of the languages as the project grows. If you only have a few strings, there is absolutely no problems with your solution.

If you have a lot of strings it could take time, memory and harddrive resources to load the language arrays on all page loads. Then you probably want to split it up to different files, or maybe even use a database backend. If using i database, consider using caching (for example memcached) so you don't need to query the database hundreds of times with every page load.

You can also check out gettext which uses precompiled language files which are really fast.