为什么它不起作用
正如文档ob_list_handlers()
中的示例所证明的那样,“URL-Rewriter”是一个输出处理程序。输出处理程序不会在进入缓冲区的数据上运行;输出处理程序在离开缓冲区的数据上运行。为了说明这一点,如果您使用并获取缓冲区的内容会发生什么?你不会得到 gz 编码的数据;你得到原始的、未压缩的数据。output_add_rewrite_var()
ob_gzhandler
从's参数的文档ob_start()
output_callback
:
当输出缓冲区被刷新(发送)或清理(使用 ob_flush()、ob_clean() 或类似函数)或在请求结束时将输出缓冲区刷新到浏览器时,将调用该函数。
这就是为什么您的第一个示例不起作用的原因。您直接使用ob_get_contents()
而不是刷新其内容来获取缓冲区的内容,因此尚未执行重写处理程序。
为什么修复有效
您发布的修复程序是正确的。由于您必须刷新缓冲区才能运行输出处理程序,因此您需要另一个输出缓冲区来捕获刷新的数据。然后该外部缓冲区将包含处理程序处理的数据,因此请获取其内容。
多个连续缓冲区的问题
关于尝试“连续运行两次”,我明白你的意思。如果在第一个缓冲区关闭后我有第二个内部缓冲区,则 URL-Rewriter 仅适用于第一个。如果我复制/粘贴并切换内部缓冲区的顺序,则工作的那个会切换。它总是最先发生的。在玩了几个小时之后,我很想说这是一个 PHP 错误,除非有一个未记录的原因表明它会专门针对 URL-Rewriter 输出处理程序以这种方式运行。
为了测试,我编写了一个简单的输出处理程序。
function ob_uppercase($buffer)
{
return strtoupper($buffer);
}
在输出处理程序的使用方面,我得到了我的预期。
// outer buffer
ob_start();
print_r(ob_list_handlers());
// inner buffer 1
ob_start('ob_uppercase');
print_r(ob_list_handlers());
ob_end_flush();
print_r(ob_list_handlers());
// inner buffer 2
ob_start('ob_uppercase');
print_r(ob_list_handlers());
ob_end_flush();
print_r(ob_list_handlers());
/*
Yields:
Array
(
[0] => default output handler
)
ARRAY
(
[0] => DEFAULT OUTPUT HANDLER
[1] => OB_UPPERCASE
)
Array
(
[0] => default output handler
)
ARRAY
(
[0] => DEFAULT OUTPUT HANDLER
[1] => OB_UPPERCASE
)
Array
(
[0] => default output handler
)
*/
现在,如果我对 URL-Rewriter 做同样的事情,它不会在第二个“内部缓冲区”中使用。
// outer buffer
ob_start();
print_r(ob_list_handlers());
// inner buffer 1
ob_start();
output_add_rewrite_var('var', 'value');
print_r(ob_list_handlers());
ob_end_flush();
print_r(ob_list_handlers());
// inner buffer 2
ob_start();
output_add_rewrite_var('var', 'value');
print_r(ob_list_handlers());
ob_end_flush();
print_r(ob_list_handlers());
/*
Yields:
Array
(
[0] => default output handler
)
Array
(
[0] => default output handler
[1] => URL-Rewriter
)
Array
(
[0] => default output handler
)
Array
(
[0] => default output handler
[1] => default output handler
)
Array
(
[0] => default output handler
)
*/
我是否在两个内部缓冲区中使用相同的 var 名称并不重要。output_add_rewrite_var()
无论 var 是什么,第二个内部缓冲区中的所有使用都被完全忽略。(我还测试了两个以上,在所有情况下只有第一个有效。)
我说这是一个错误。如果您同意,请向http://bugs.php.net提交错误报告。