0

为什么这不起作用?

output_add_rewrite_var('var', 'value');

// some links
echo '<a href="file.php">link</a>
<a href="http://example.com">link2</a>';

// a form
echo '<form action="script.php" method="post">
<input type="text" name="var2" />
</form>';

$tmp = ob_get_contents();

#print_r(ob_list_handlers());

ob_end_clean();

echo $tmp;

取自http://www.php.net/manual/en/function.ob-get-contents.php

我找到了一个修复

ob_start();
ob_start();
output_add_rewrite_var('var', 'value');

// some links
echo '<a href="file.php">link</a>
<a href="http://example.com">link2</a>';

// a form
echo '<form action="script.php" method="post">
<input type="text" name="var2" />
</form>';

ob_end_flush();

$tmp = ob_get_contents();

#print_r(ob_list_handlers());

ob_end_clean();

echo $tmp;

修复不起作用

如果我尝试连续运行两次,则修复不起作用,第一次运行良好,最后一次根本不添加“?var = value”。有人有线索吗?

4

1 回答 1

3

为什么它不起作用

正如文档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提交错误报告。

于 2011-04-30T04:44:27.953 回答