PHP 8.1 Alpine Docker容器中NumberFormatter始终返回默认en_US区域设置问题排查
Hey there, let's break down this issue and fix it step by step!
问题回顾
You're running into a weird behavior with NumberFormatter in a PHP 8.1 Alpine Docker container: when you specify nl_NL as the locale, getLocale() keeps returning en_US, and the currency format doesn't match Dutch expectations (you get €1,234.57 instead of €1.234,57). Oddly enough, en_GB works perfectly fine.
Here's how you're reproducing it:
- Spin up and enter the container:
docker run -it --rm php:8.1-fpm-alpine /bin/ash - Install dependencies and the intl extension:
apk update && apk add icu-dev docker-php-ext-configure intl && docker-php-ext-install intl - Test in PHP interactive mode:
$formatter = new NumberFormatter('nl_NL', NumberFormatter::CURRENCY); echo $formatter->getLocale(); // Outputs en_US (unexpected) echo $formatter->format(1234.567); // Outputs €1,234.57 (unexpected)
Your expected outcome is:
getLocale()returnsnl_NL- Currency formatted to Dutch standards:
€1.234,57
Root Cause & Fixes
The main issue here is that Alpine Linux's default ICU packages don't come with full locale data pre-installed. Let's fix this with a few options:
1. Install the full ICU locale data package
The icu-dev package you installed only includes development headers, not the complete locale definitions. Install the full data package:
apk add icu-data-full
After installing this, restart your PHP process (or exit and re-enter the container) and test again. This should make nl_NL recognizable, and the currency format will switch to the Dutch style.
2. Use the full locale identifier with encoding
Sometimes Alpine requires a more precise locale string, including the encoding. Try modifying your PHP code to use nl_NL.UTF-8 instead:
$formatter = new NumberFormatter('nl_NL.UTF-8', NumberFormatter::CURRENCY);
This often helps the ICU library correctly resolve the locale.
3. Set the system-wide locale
If the above don't work, you can explicitly generate and set the Dutch locale at the system level:
# Install locale tools apk add locale # Add the Dutch locale to the generation list echo "nl_NL.UTF-8 UTF-8" >> /etc/locale.gen # Generate the locale locale-gen # Set environment variables to use Dutch locale export LC_ALL=nl_NL.UTF-8 export LANG=nl_NL.UTF-8
Once you've done this, launch the PHP interactive shell again, and the NumberFormatter should behave as expected.
Suggestions to Improve Your Question
To make your question even clearer for other developers, you could phrase it like this:
When using
NumberFormatterwithnl_NLin a PHP 8.1 Alpine Docker container,getLocale()returnsen_USinstead of the specified locale, and currency formatting uses US-style separators instead of Dutch ones. However,en_GBworks correctly. How can I fix this?
This cuts straight to the core issue, highlighting the inconsistent behavior between locales which helps others diagnose faster.
内容的提问来源于stack exchange,提问作者Frank

