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         
top<https://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 <[email protected]>
Sent: 29 October 2025 09:45
To: Marc Henderkes <[email protected]>
Cc: [email protected]
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 <[email protected]<mailto:[email protected]>> 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

Reply via email to