php - 带有 ob_start 回调函数的 ob_get_clean
问题描述
我正在尝试使用多个 ob_start 获得缓冲输出。有些 ob_start 有回调函数。函数调用但没有效果。
<?php
function callback($buffer)
{
return "deleted\n";
}
ob_start();
echo "first\n";
ob_start("callback");
echo "second\n";
ob_start();
echo "third\n";
$final = '';
$levels = ob_get_level();
for ($i = 0; $i < $levels; $i++) {
$final .= ob_get_clean();
}
echo $final;
预期结果是
third
deleted
first
但我明白了
third
second
first
我做错了什么?
解决方案
我也对此感到惊讶,并且文档可能对此更加清楚。根据文档:
ob_get_clean() 本质上同时执行 ob_get_contents() 和 ob_end_clean()。
但是,$callback
of在以下情况下ob_start($callback)
被调用:
[...] 输出缓冲区被刷新(发送)或清理(使用 ob_flush()、ob_clean() 或类似函数)或在请求结束时将输出缓冲区刷新到浏览器时。
当$callback
被调用时ob_get_contents()
已经被调用并且它对 没有影响$contents
。
我们可以在PHP 源代码中确认:
PHP_FUNCTION(ob_get_clean)
{
if (zend_parse_parameters_none() == FAILURE) {
RETURN_THROWS();
}
if(!OG(active)) {
RETURN_FALSE;
}
if (php_output_get_contents(return_value) == FAILURE) {
php_error_docref("ref.outcontrol", E_NOTICE, "Failed to delete buffer. No buffer to delete");
RETURN_FALSE;
}
if (SUCCESS != php_output_discard()) {
php_error_docref("ref.outcontrol", E_NOTICE, "Failed to delete buffer of %s (%d)", ZSTR_VAL(OG(active)->name), OG(active)->level);
}
}
我不认为有办法解决这个问题。您需要小心使用ob_get_contents()
. 如果要堆叠多个输出处理程序,请仅使用ob_start($callback)
s. 如果可以选择调用$callback
onob_get_contents()
和等效项,那肯定会很好。
推荐阅读
- python - 尽管安装了 Django,但找不到 Django-Admin
- python - 在 Python 中使用 for 循环的数组上的 .strip() 不起作用?
- javascript - 将类内的对象分配给javascript中的变量
- c# - Razor 运行时编译不适用于动态加载的程序集
- javascript - 如果用户输入了不可接受的内容,我该如何重置程序?
- primefaces - CDI Flow Scope Bean 不适用于包含/组合 xhtml 标记
- regex - 评估字符串中的 RegEx 模式
- typescript - 对象字面量只能指定已知属性,并且“RatesWhereUniqueInput”类型中不存在“clientId”
- firebase - 方法 'toInt' 不能被无条件调用,因为接收者在 Dart 中可以是 'null'
- python - Amazon SP API:Feeds API 处理报告神秘错误代码和消息