我不確定這是一個錯誤還是一個功能。查看PHP源代碼,我發現返回值ob_get_clean
在調用回調之前被填充。
我看到至少有兩種解決方法。首先是自己手動調用輸出字符串的回調。我認爲這不需要例子。
其次是利用堆疊輸出緩衝的可能性。由於flush成功地使用了回調函數,因此可以將輸出代碼封裝在附加的輸出緩衝區中並獲取修改後的內容。
ob_start();
function callback($input) { return $input . " altered"; }
ob_start('callback');
echo "foo";
ob_end_flush();
$content = ob_get_clean();
ob_end_clean();
echo $content . "\n"; // prints "foo altered\n"
見ob_get_clean
(主/ output.c)的源代碼,如果你很好奇。你可以在PHP網站上獲得源代碼。這裏有一些指針。
/* {{{ proto bool ob_get_clean(void)
Get current buffer contents and delete current output buffer */
PHP_FUNCTION(ob_get_clean)
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}
// THIS CALL FILLS THE RETURN VALUE
if (php_ob_get_buffer(return_value TSRMLS_CC) == FAILURE) {
RETURN_FALSE;
}
if (!OG(ob_nesting_level)) {
php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete");
zval_dtor(return_value);
RETURN_FALSE;
}
if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) {
php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s", OG(active_ob_buffer).handler_name);
zval_dtor(return_value);
RETURN_FALSE;
}
// THIS CALL KILLS THE CURRENT BUFFER AND EXECUTES THE CALLBACK
php_end_ob_buffer(0, 0 TSRMLS_CC);
}
/* }}} */
php_end_ob_buffer
採取OB緩衝區的內容和回調適用於它。如果第一個參數爲true,則它將內容傳遞給下一個輸出緩衝處理程序。在這種情況下,它是錯誤的,所以即使執行了回調,內容也會丟失。
是否php手冊說這包括ob_get_clean()?你的實驗是一個強有力的論點,說它沒有。此外,似乎緩衝區正在被修改,但get的結果不是。 – 2012-09-12 16:19:54