3

コールバック関数を備えた出力バッファがあります。バッファを消去すると、コールバック関数が実行されますが、返される文字列は変更されていません。

私は次のコードを使用しています:

<?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() または同様の関数を使用) されたとき、または出力バッファがリクエストの最後にブラウザにフラッシュされたときに呼び出されます。

4

6 に答える 6

8

これがバグなのか機能なのかはわかりません。PHP のソース コードを見るとob_get_clean、コールバックが呼び出される前に の戻り値が満たされていることがわかりました。

少なくとも 2 つの回避策があります。1 つ目は、出力文字列に対して自分でコールバックを手動で呼び出すことです。これは例えがいらないと思います。

2 つ目は、出力バッファリングをスタックする可能性を利用することです。フラッシュはコールバックを正常に使用するため、出力コードを追加の出力バッファー内にラップして、変更された内容を取得できます。

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興味がある場合は、(main/output.c)のソース コードを参照してください。ソース コードは、PHP の Web サイトで入手できます。ここにいくつかの指針があります。

/* {{{ 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_bufferOB バッファの内容を取得し、それにコールバックを適用します。最初のパラメーターが true の場合、内容を次の出力バッファリング ハンドラーに渡します。この場合は false であるため、コールバックを実行してもコンテンツは失われます。

于 2012-09-12T16:33:51.123 に答える
1

推しだとしたらこれだ。

ob_get_clean()バッファの結果を返し、それをクリーニングして、コンテンツを変更するコールバックをトリガーします。

IE

「何らかのテキスト」がバッファから抽出され、「取得」機能の要件に従って返される準備ができています。

次に、バッファーが消去されますが、消去する前に、コールバックが存在する場合のさまざまな ob 関数の要件に従って、コンテンツに対してコールバックがトリガーされます。

その結果、バッファーは (要求どおりに) 返されますが、クリーンの前に取得が行われるため、後で変更されます。

于 2012-09-12T16:25:26.303 に答える
-1

バッファがフラッシュされたときに呼び出されます。

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

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

PS CLIでも動作します。

于 2012-09-12T16:04:04.760 に答える
-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() メソッドを使用するのですか? バッファをクリーンアップします。

于 2012-09-12T16:12:58.183 に答える
-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)
    );
  }
?>
于 2012-09-12T16:26:49.210 に答える
-1

PHP の CLI は、出力バッファリングを使用しません (具体的には、バッファリングは ob_ 関数とは関係ありません)。したがって、コールバックはスキップされています。

EDIT:実際には、CLIで標準出力バッファリングが利用できるかどうかを確認するのに苦労しています。ob_end_flush()、、、ob_flush()およびを試してみflush()ます。

于 2012-09-12T16:03:09.050 に答える