Проблема
Я использую PHP apache_note()
для записи переменных из веб-запросов в формат CustomLog. Однако, как бы я ни старался, Apache не хочет регистрировать символы UTF-8 так, как мне хотелось бы.
В PHP у меня есть apache_note('some_value', '✔');
что соответствует конфигурации VHost, которая выглядит так:
LogFormat "%{some_value}n" custom_format
CustomLog ${APACHE_LOG_DIR}/access.log custom_format
Однако Apache в конечном итоге записывает буквальную версию следующим образом:
\xe2\x9c\x94
Что я пробовал
LANG
и LC_ALL
и они оба настроены на en_US.UTF-8
/etc/apache2/envvars
использовать /etc/default/locale
по умолчаниюCharsetSourceEnc UTF8
и CharsetDefault UTF8
в конфигурации Apache для сайта (я знаю, что это для ввода / вывода контента)AddDefaultCharset UTF-8
\xe2\x9c\x94
к тому моменту, когда он туда попадает, кажется, что это как-то связано с самим процессом Apache.В конечном итоге я хочу, чтобы в журнале доступа отображалось что-то вроде:
✔
но я выдергиваю волосы, пытаясь добраться туда.
Дополнительная информация
Обновить
По предложению Эсы я изменил LogFormat
директива:
LogFormat "%{some_value}n ✔" custom_format
И я получаю следующее:
\xe2\x9c\x94 ✔
Это интересно, потому что предполагает готовность Apache регистрировать UTF-8. Однако я все еще не уверен, что проблема связана с передачей PHP значений, отличных от UTF-8.
apache_note('some_value', '✔');
$value = apache_note('some_value');
print_r($value);
в PHP все еще распечатывает
✔
Я попробую перекомпилировать Apache, чтобы убедиться, что это помогает, но мне это действительно нужно в производственной среде, что может быть рискованно.
Вы обнаружите, что это экранируется в ap_escape_logitem. Взгляните на следующий код. Он использует макрос TEST_CHAR, чтобы определить, что нужно экранировать, но вывод в основном ASCII
https://github.com/apache/httpd/blob/5ed78e19a21609f7097f9049b2fe6db8e471f810/server/util.c
Экранированное ведение журнала - это особенность
Начиная с 2.0.49, API ведения журналов Apache избегает всего, что попадает в error_log, поэтому, если вас раздражает эта функция на этапе разработки (так как ваши сообщения об ошибках будут испорчены), вы можете отключить экранирование во время сборки Apache. время:
% CFLAGS="-DAP_UNSAFE_ERROR_LOG_UNESCAPED" ./configure ...
Не используйте эти CFLAGS в производстве, если вы не знаете, что делаете.