12

I want to start using gettext to handle my translations on web projects (PHP 5). Since it is a widely used standard with a good reputation it seems to be the best choice.

However, I'm also hearing things about server incompatibly and it being non-thread-safe. What does this mean for my projects that use it then? Since I build things that many people use, it's very important that my code works.

Are we talking about minor problems (like people still using PHP 4) or major problems like distribution and installation of gettext on websevers being low?

Xeoncross
  • 55,620
  • 80
  • 262
  • 364

3 Answers3

16

Threads problem only apply if one uses embedded PHP (Apache's mod-php for example) and runs server that uses threads (like Apache server with worker-mpm).

So - thread safety issue does not apply to you if:

  1. you use NGINX server(it doesn't use threads.)
  2. You use Apache (with either threaded MPM or not) and PHP in fastcgi mode
  3. You use Apache with non-threaded MPM (as prefork-MPM) and PHP in mod-php mode.

So - most people with default Apache install shouldn't worry about gettext not being thread safe, as default apache's install in most distro's uses non-threaded prefork-MPM!

P.S. also - keep in mind that Apache on Windows is threaded.

ThatGuy
  • 14,941
  • 2
  • 29
  • 26
  • I run PHP as 10 fastcgi processes on linux that are called on by nginx when needed. If you run the PHP process as a CGI is that threaded? – Xeoncross Jul 17 '11 at 23:11
  • 1
    @Xeoncross : you have nothing to worry about. Nginx doesn't use threads. And also - you run PHP as CGI (PHP-FPM I hope) - thus it operates just like a server on it's own, no locale related gettext racing conditions are possible. – ThatGuy Jul 17 '11 at 23:32
  • Actually, I'm still running it as a daemon - I need to switch to PHP-FPM now that it comes with PHP 5.3. – Xeoncross Jul 18 '11 at 01:15
2

I think play some more with the php manual comments portion should revile more information....one of the comments from the manual on gettext section

The GNU gettext library works on a per-process, not per-thread basis. This means that in a multi-user setting such as the Apache web server it will only work with a prefork MPM (i.e. one process per user). Worker and other threaded MPMs will not work.

In addition, many users control GNU gettext by setting system environment variables such as LANG. This is not a good solution for a web server environment due to an obvious race condition.

http://www.php.net/manual/en/gettext.setup.php

Ronald Conco
  • 855
  • 7
  • 11
  • 1
    I guess the question then is, what good is the LANG variable if you can't change it at run time after you know what lang the user wants? What would be the point of gettext then? – Xeoncross Oct 29 '09 at 20:44
  • Indeed, since environment variables are per process, I am having trouble seeing the race condition.... If you are trying to have different threads serve different translations, you will want something different of course. – Chris Travers Nov 11 '14 at 00:24
0

I had same problem with PHP 5.6.30 VC11 Theard Safe on Windows 10. Workaround found and fix this issue here by sirio3mil.

Apparently PHP with TS can access only Locale language folder. So when setlocale and putenv function is call with another language than system's one, folder with .mo and .po cannot be read.

Workaround is to have only one language folder with system language and multiple pairs of .mo/.po files for each translated languages. Domain will be set with wanted language.

Example with Swiss French, German and Italian:

Folder structure

\Locale\fr_CH\LC_MESSAGES

  • fr_CH.mo + fr_CH.po // system language
  • de_CH.mo + de_CH.po
  • it_CH.mo + it_CH.po

Code

$lang = 'fr_CH' or 'de_CH' or 'it_CH'

bindtextdomain($lang, '.\Locale');
textdomain($lang);
bind_textdomain_codeset($lang, 'UTF-8');
setlocale (LC_ALL, $lang);
putenv('LC_ALL=' . $lang);
Community
  • 1
  • 1
Camille
  • 2,439
  • 1
  • 14
  • 32