Вывод NumberFormatter неверен на веб-сервере, а не на другом - PullRequest
0 голосов
/ 06 июня 2019

Контекст: мы создаем файлы CSV и PDF, содержащие числа, отформатированные во французском формате (разделитель тысяч - это пробел без перерывов).

При чтении файлов CSV или PDF при загрузке с рабочего сервера вместо пробела появляется символ ?. При загрузке с нашего сервера разработки мы получаем правильные файлы.


У нас есть небольшой скрипт, который помог обеспечить минимальное воспроизведение.

header('Content-Description: File Transfer');
header('Content-Type: text/plain; charset=UTF-8');
header('Content-Disposition: attachment; filename="'.date('YmdHis').'.txt"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');

$fmt = new NumberFormatter('fr_FR', NumberFormatter::DECIMAL);
$fmt->setAttribute(NumberFormatter::FRACTION_DIGITS, 2);

echo $fmt->format(12390);

Этот скрипт корректно работает на виртуальной машине.

Шестнадцатеричное содержимое загружаемого файла:

31 32 c2 a0 33 39 30 2c 30 30 

c2 a0 являющийся пространством без перерывов UTF-8

При запуске на нашем производственном сервере точно такой же сценарий выводит файл, содержащий следующее шестнадцатеричное содержимое:

31 32 e2 80 af 33 39 30 2c 30 30

e2 80 af - это то, что отличает его от вышеупомянутого. Похоже, это узкий непрерывный символ из Unicode, закодированный в UTF-8

Что мы делаем не так?

  • Мы попытались сравнить конфигурации PHP и Nginx, но они очень похожи и не смогли найти ничего, связанного с кодировкой.
  • Расширение mbstring включено с обеих сторон.
  • Когда мы комментируем заголовок для принудительной загрузки, текст корректно отображается браузером на обоих серверах (нет ?)

Обновление

По какой-то причине на сервере языковой стандарт fr_FR использует обычный неразрывный пробел. В то время как на другом сервере тот же код заканчивается языком, использующим узкий неразрывный пробел.

Похоже, что в разных инструментах плохая поддержка узкого неразрывного пространства.

Текущий обходной путь заключается в принудительном использовании обычного неразрывного пробела, и в итоге он работает должным образом. Это далеко не идеал.

Если у кого-то есть объяснение, почему один и тот же языковой стандарт приводит к другому символу группировки, я был бы рад прочитать его и узнать, как получить согласованную настройку между серверами.

...