2012-09-12 89 views
2

我有一個帶回調函數的輸出緩衝區。清理緩衝區時,執行回調函數,但返回的字符串未被更改。PHP:輸出緩衝區回調沒有改變輸出

我用下面的代碼:

<?php 
ob_start('callback'); 
print 'some text'; 
error_log(ob_get_clean()); 

function callback($content) { 
    error_log('callback'); 
    return $content . ' altered'; 
} 

輸出:

callback 
some text 

我想要什麼:

callback 
some text altered 

我缺少什麼?我在CLI中使用PHP 5.3.10。

編輯:正在執行回調。

從PHP手冊:

當輸出緩衝器被刷新的功能將被調用(發送) 或清潔(與使用ob_flush(),ob_clean()或類似功能),或當 的輸出緩衝區在請求結束時刷新到瀏覽器。

+0

是否php手冊說這包括ob_get_clean()?你的實驗是一個強有力的論點,說它沒有。此外,似乎緩衝區正在被修改,但get的結果不是。 – 2012-09-12 16:19:54

回答

6

我不確定這是一個錯誤還是一個功能。查看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,則它將內容傳遞給下一個輸出緩衝處理程序。在這種情況下,它是錯誤的,所以即使執行了回調,內容也會丟失。

-1

用於PHP的CLI不使用輸出緩衝(或者更具體地說拋光與ob_函數無關)。所以你的回調被跳過。

編輯:其實我無法確認標準輸出緩衝是否可用在CLI。我會嘗試ob_end_flush(),ob_flush()flush()

+0

我可以看到添加調試消息時正在執行回調。 – Bart

+0

輸出緩衝_does_在CLI模式下工作。 – zneak

-1

當緩衝區刷新它將被稱爲:

ob_start('callback'); 
print 'some text'; 
ob_end_flush(); 

function callback($content) { 
    return $content . ' altered'; 
} 

附: 它也適用於CLI。

-1

我刪除ob_get_clean,你的代碼確實有效。

ob_start('callback'); 
print 'some text'; 
//error_log(ob_get_clean()); 

$buffer = ob_get_flush(); 

function callback($content) { 
    return $content . ' altered'; 
} 

我檢查輸出,它是一些文本警報。

爲什麼使用ob_get_clean()方法?它清理緩衝區。

+0

我可以看到很好的理由來清理緩衝區。 – zneak

+0

我沒有使用它,第三方是。還有成千上萬的原因。 – Bart

1

如果我有一個猜測就是這樣。

ob_get_clean()正在返回緩衝區的結果,並且然後清除它,觸發修改內容的回調。

IE

「一些文本」從緩衝器中提取,並準備返回爲每的「GET」的功能要求。

接下來,清理緩衝區,但在清理之前,根據內容觸發回調,根據回調時各種ob函數的要求。

結果是緩衝區被返回(按要求),但之後被修改,因爲get發生在clean之前。

-1
<?php ob_start('callback'); ?> 

    Foo Bar Baz 

<?php 
    ob_end_flush(); 

    function callback($content) { 
    $find = "Baz"; 
    $replace_with = "Foo"; 
    return (
     str_replace($find, $replace_with, $content) 
    ); 
    } 
?>