Last week, as part of my first ever foray into the internationalisation of a web application written in PHP, I was RTFM on setlocale() and, as is my want, I skimmed the comments at the bottom as well, because they often contain useful little gems that can save you a ton of time. If you didn’t bother clicking on that link, here’s the key bit:
The locale information is maintained per process, not per thread. If you are running PHP on a multithreaded server api like IIS or Apache on Windows you may experience sudden changes of locale settings while a script is running although the script itself never called setlocale() itself. This happens due to other scripts running in different threads of the same process at the same time changing the processwide locale using setlocale().
The comments go on to list numerous examples from many poor sods who have missed this warning and have gone on to experience seemingly inexplicable and apparently (at least at first) random changes of character encodings and other subtle (or not so subtle) locale settings during the execution of their apps.
I’m sorry, but I couldn’t stop chuckling to myself for days, only because I’ve experienced similar bugs myself (particularly with embedded Point Of Sale terminals - yes, I’m talking about you, Ingenico and VeriFone!!!) and can relate to the situation quite well. What makes this particular issue even more insidious is that solo developers probably wouldn’t spot it unless they were (A) really lucky, (B) had a strict policy of carrying out some concurrency testing with multiple users prior to deployment or (C) used some kind of automated test system like Selenium that included some concurrent tests.
Oh, the irony that I have been developing on/with Windows for over 15 years (if you consider using a 3270 emulator to hack PL/1 code and JCL scripts in 1993 to be “developing on/with Windows” :-) and I just migrated off Windows a few weeks before I started using setlocale()... woo hoo!