docs: Document gettext incompatibility
gettext is not thread safe and can only load a single locale per process, this causes a mix and match of languages to be returned from translations.
https://stackoverflow.com/a/1646343
This should be added to the php documentation as well. And maybe php should even fail to compile gettext extension in a ZTS build?
Does it also affect the intl extension, considering that libintl is part of the gettext package?
After further research, it seems this isn't strictly gettext specific but in fact related to setlocale having a process-wide effect on Linux. I should probably change the reason then.
This probably also affects libintl in general whenever changes to the locale occur but I'm not 100% sure either. How should we go about documenting it ?
I wonder if this couldn't be changed in php-src. uselocale() does the same as setlocale(), but it's mt-safe and only affects the current thread.
I will create a php RFC to rework setlocale() to use uselocale() on Posix too.
I have a POC working, but it's more complicated than I'd hoped, because uselocale doesn't support setting individual locales. I need to createlocale with the intended masks and free old locales, if no longer required. To convert them to locale strings individually, we need to track one per available LC_ constant,, which is 5 in general and then another 5 gnu extensions.
Tl;dr: working, but messy.
Given the following PHP code to simulate different FrankenPHP requests:
<?php
use parallel\Runtime;
setlocale(LC_ALL,'C');
echo "main@start : ".setlocale(LC_ALL,0)." | dp=".localeconv()['decimal_point']."\n";
$f = (new Runtime())->run(function () {
setlocale(LC_ALL,'de_DE.UTF-8');
echo "worker@set : ".setlocale(LC_ALL,0)." | dp=".localeconv()['decimal_point']."\n";
});
echo "main@after : ".setlocale(LC_ALL,0)." | dp=".localeconv()['decimal_point']."\n";
$f->value();
Currently:
[m@M bin]$ php -d "extension=/home/m/static-php-cli/buildroot/modules/parallel.so" localetest.php
main@start : C.UTF-8 | dp=.
worker@set : de_DE.UTF-8 | dp=,
main@after : de_DE.UTF-8 | dp=,
Expected, after proposed implementation:
[m@M bin]$ ./php -d "extension=/home/m/static-php-cli/buildroot/modules/parallel.so" localetest.php
main@start : C.UTF-8 | dp=.
worker@set : de_DE.UTF-8 | dp=,
main@after : C.UTF-8 | dp=.
Hi, I'm facing the very same issue right now and it would be great to see a fix for this soon. I also created a small demo with Copilot to demonstrate and test this issue with an actual web app. https://github.com/Seros/frankenphp-setlocale-demo
It's "working as documented" for php. I've brought it into php-internals circulation, but the fix does not lie in our (frankenphp) domain.
Will update when there's news.