问题
我使用 PHP 将apache_note()
Web 请求中的变量记录为 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
- 我已使用 mod_charset_lite 设置了
CharsetSourceEnc UTF8
网站CharsetDefault UTF8
的 Apache 配置(我知道这是用于内容输入/输出) - 检查 /etc/apache2/conf.d/charset 是否已设置
AddDefaultCharset UTF-8
- 尝试通过管道日志将日志输出发送到另一个程序 -
\xe2\x9c\x94
当它到达那里时,它肯定看起来与 Apache 进程本身有关。 - 通读Apache 日志文档
最终,我希望访问日志显示类似以下内容:
✔
但我正竭尽全力试图到达那里。
其他信息
- Apache 版本 2.4.10
- Debian 8.4
更新
根据 Esa 的建议,我修改了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,看看它是否有帮助,但我在生产中确实需要它,这可能会有风险。
答案1
从 2.0.49 开始,Apache 日志记录 API 会转义进入 error_log 的所有内容,因此如果您在开发阶段对该功能感到烦恼(因为您的错误消息会变得混乱),您可以在 Apache 构建时禁用转义:
% CFLAGS="-DAP_UNSAFE_ERROR_LOG_UNESCAPED" ./configure ...
除非您清楚自己在做什么,否则请勿在生产中使用 CFLAGS。
答案2
您会发现它在 ap_escape_logitem 中被转义。看看下面的代码。它使用一个名为 TEST_CHAR 的宏来确定需要转义的内容,但输出基本上是 ASCII
https://github.com/apache/httpd/blob/5ed78e19a21609f7097f9049b2fe6db8e471f810/server/util.c