5

I'm following the instructions from BryanH's answer here: gettext() equivalent in Intl library? and trying to implement localization (translation) with php-intl, but I keep getting the same problem this person had: ResourceBundle returns NULL without any errors being raised

He mentions he created the dat files with a tool (which I cannot figure out how to work) while the person in the former answer simply appears to be using txt files with a .res extension.

How do I properly implement localization with php-intl and ResourceBundle, and what am I doing wrong?

The goal is to have various data files with different languages so I can do something similar to

$t = new Translator();
$t->setResource(new \ResourceBundle('es', 'locales_folder/'));
$t->echo("somestring"); // "el stringo"

..much like the person in the first answer had. Also, the aim is to have easily editable files, so I can give them to translators for fixes, updates, and so on. I realize I could easily do this with custom solution through a simple text file which gets parsed and saved into memcache on first request, where it then persists and gets served from without having to re-read the .dat files, but I'd rather take the suggested route here.

Edit: Just to get it out there - I implemented the same thing with gettext successfully and it was dead easy - save for one bug that persists across linux systems (http://www.php.net/manual/en/book.gettext.php#91187) - but I'd like to rely on the more modern and all-inclusive intl extension if possible.

Community
  • 1
  • 1
Swader
  • 11,387
  • 14
  • 50
  • 84

1 Answers1

9

I can provide a solution to your question on how to create and use .res files for the intl PHP extension, however I have no experience with speed and use in production systems, you will have to see for yourself if this can be a replacement for gettext.

In my opinion a great benefit of gettext are additional tools such as xgettext which can extract strings to be translated. Still, using resources might be more useful in your use-case.

To generate a .res file you need to use the program genrb which is bundled with ICU. (for example when installing ICU on OSX using brew install icu4c (see this tutorial) you can find the tool at /usr/local/Cellar/icu4c/*/bin/genrb (replace * with the version number))

Next you prepare a file for each locale. Let's do this for two languages in this example, German and Spanish.

$ cat de.txt
de {
    hello { "Hallo" }
}

$ cat es.txt
es {
    hello { "Hola" }
}

$ genrb *.txt
genrb number of files: 2

You now have 2 additional files de.res and es.res, which you can now access in PHP

<?php
foreach (array("de", "es") as $locale) {
    $r = ResourceBundle::create($locale, __DIR__);
    echo $r["hello"], "\n";
}

which will output

Hallo
Hola

So in essence, you can hand those *.txt files to your translaters and prepare them for PHP using genrb.

Finally, a small example for the class you were trying to write:

<?php
class Translator {
    private $resourceBundle = null;

    public function __construct(\ResourceBundle $r) {
        $this->resourceBundle = $r;
    }

    public function __get($string) {
        return $this->resourceBundle[$string];
    }
}
$t = new Translator(new \ResourceBundle('es', __DIR__));
echo $t->hello;
akirk
  • 6,757
  • 2
  • 34
  • 57
  • Thanks, that'll do. Since this is supposed to be thread safe, I reckon it's the solution I was looking for. Now I'll just need to write my own string extractor and that should work. – Swader Jun 18 '13 at 20:11
  • 1
    It would be very useful if you could share you experience with it, also with your string extractor (maybe you could even open source it?). Thanks in advance! – akirk Jun 19 '13 at 07:19
  • Since poedit can auto-extract for gettext, I figured I could just give it another pattern to look for like $t->_($string), which would then create .mo and .po files for those strings too. All I would have to do then is write a tool that converts those into RES format, which sounds fairly easy. I'll write a blog post about the entire ordeal and link it here. – Swader Jun 19 '13 at 12:38
  • 1
    @Swader ICU has tools that convert to and from XLIFF format. Could pivot through that as well. I've considered converting to and from po, mo, .properties, .rc, etc also. – Steven R. Loomis Jun 22 '13 at 02:08
  • Yup, that's what I'll be doing - converting from po files into res, seems the easiest since poedit so wonderfully extracts everything out of a project. – Swader Jun 22 '13 at 06:57