Hello everyone,
We recently noticed that the setlocale function currently uses setlocale in its C implementation as well [https://github.com/php/frankenphp/pull/1941], which is a) not multithreading safe to use and b) when it doesn't crash, leads to overriding the current locale for the entire process.
For NTS builds with php-fpm this is not an issue, but for FrankenPHP and mod_php, this leads to unexpected behaviour described here: https://github.com/php/frankenphp/pull/1941#issuecomment-3457137937
On Windows builds, since PHP 7, it is already per-thread, but on POSIX systems it is not.
I would therefore like to get your reactions on whether it would make sense to unify the behaviour between POSIX systems and Windows and make the setlocale() function thread-safe and per-thread, rather than per-process.
In case my proposal sees positive reception, I'd like to go ahead and create an RFC. I will also implement the changes in php-src, I've already done so as a proof of concept.
Thank you for your time,
Marc Henderkes
Le 28 oct. 2025 à 16:52, Marc Henderkes m@pyc.ac a écrit :
Hello everyone,
We recently noticed that the setlocale function currently uses
setlocalein its C implementation as well [https://github.com/php/frankenphp/pull/1941], which is a) not multithreading safe to use and b) when it doesn’t crash, leads to overriding the current locale for the entire process.
For NTS builds with php-fpm this is not an issue, but for FrankenPHP and mod_php, this leads to unexpected behaviour described here: https://github.com/php/frankenphp/pull/1941#issuecomment-3457137937On Windows builds, since PHP 7, it is already per-thread, but on POSIX systems it is not.
I would therefore like to get your reactions on whether it would make sense to unify the behaviour between POSIX systems and Windows and make the
setlocale()function thread-safe and per-thread, rather than per-process.
In case my proposal sees positive reception, I’d like to go ahead and create an RFC. I will also implement the changes in php-src, I’ve already done so as a proof of concept.Thank you for your time,
Marc Henderkes
Hi,
From my point of view, the current behaviour (not thread-safe and not per-thread) is obviously a bug, not a feature. I assume that there is no need to create an RFC for fixing a bug?
—Claude
Hello Claude,
I assume it’s not a bug because it’s the documented in the manual at https://www.php.net/manual/en/function.setlocale.php
Warning The locale information is maintained per process, not per thread. If you are running PHP on a multithreaded server API , you may experience sudden changes in locale settings while a script is running, though the script itself never called setlocale(). This happens due to other scripts running in different threads of the same process at the same time, changing the process-wide locale using setlocale(). On Windows, locale information is maintained per thread as of PHP 7.0.5.
This is due to POSIX setlocale documented here: https://man7.org/linux/man-pages/man3/setlocale.3.html
ATTRIBUTES tophttps://man7.org/linux/man-pages/man3/setlocale.3.html#top_of_page
For an explanation of the terms used in this section, see
attributes(7)https://man7.org/linux/man-pages/man7/attributes.7.html.
┌───────────────────┬───────────────┬────────────────────────────┐
│ Interface │ Attribute │ Value │
├───────────────────┼───────────────┼────────────────────────────┤
│ setlocale() │ Thread safety │ MT-Unsafe const:locale env │
The implementation I came up with is a little nasty, because uselocale(0) (https://man7.org/linux/man-pages/man3/uselocale.3.html) doesn’t return the string representation of the locale it was queried with, but the pointer to the current locale struct created by newlocale(). Therefore, I am tracking each available locale’s name when set. On BSD we could avoid that and instead querylocale (https://man.freebsd.org/cgi/man.cgi?query=querylocale), but glibc and musl do not provide such functionality.
Example implementation is here: https://github.com/henderkes/php-src/commit/b69522ff4413fb64c6e073bf9e1445f3c25f9b9a
Thanks,
Marc
From: Claude Pache claude.pache@gmail.com
Sent: 29 October 2025 09:45
To: Marc Henderkes m@pyc.ac
Cc: internals@lists.php.net
Subject: Re: [PHP-DEV] Change setlocale() to use the uselocale() C function if available on POSIX too
Le 28 oct. 2025 à 16:52, Marc Henderkes <m@pyc.acmailto:m@pyc.ac> a écrit :
Hello everyone,
We recently noticed that the setlocale function currently uses setlocale in its C implementation as well [https://github.com/php/frankenphp/pull/1941], which is a) not multithreading safe to use and b) when it doesn’t crash, leads to overriding the current locale for the entire process.
For NTS builds with php-fpm this is not an issue, but for FrankenPHP and mod_php, this leads to unexpected behaviour described here: https://github.com/php/frankenphp/pull/1941#issuecomment-3457137937
On Windows builds, since PHP 7, it is already per-thread, but on POSIX systems it is not.
I would therefore like to get your reactions on whether it would make sense to unify the behaviour between POSIX systems and Windows and make the setlocale() function thread-safe and per-thread, rather than per-process.
In case my proposal sees positive reception, I’d like to go ahead and create an RFC. I will also implement the changes in php-src, I’ve already done so as a proof of concept.
Thank you for your time,
Marc Henderkes
Hi,
From my point of view, the current behaviour (not thread-safe and not per-thread) is obviously a bug, not a feature. I assume that there is no need to create an RFC for fixing a bug?
—Claude
I assume it’s not a bug because it’s the documented in the manual at https://www.php.net/manual/en/function.setlocale.php
Perhaps "known limitation" is a better term than "bug". I don't think anyone considers this a feature, or would deliberately make use of it; the general advice is just "don't use it in multi-threaded contexts".
This was one of the main reasons given for deprecating strftime() in PHP 8.1 - because it was not thread safe, users should be encouraged to use something else. https://wiki.php.net/rfc/deprecations_php_8_1#strftime_and_gmstrftime
Removing that limitation is not likely to be controversial, in principle. What is probably needed is detailed technical discussion of the proposed approach, so a Pull Request is probably more relevant than an RFC.
[PS: policy on this list is to edit quoted text and place your reply below, as I've done here, rather than above as many email clients do by default]
Rowan Tommins
[IMSoP]