2

これを使って何かメリットがあるのか​​気になる…

function getSomeContent() {
    ob_start(function($content) {
        // ... modify content ...
        return $content;
    }
    // ... output stuff ...
    return ob_get_clean();
}

…これに対して…

function getSomeContent() {
    ob_start();
    // ... output stuff ...
    $result = ob_get_clean();
    // ... modify content ...
    return $result;
}

...?

「出力内容」と「コンテンツの変更」の部分は、いずれの場合も同じであると仮定します。重要な点は、「コンテンツの変更」がその場所を変更したことです。最初のケースではコールバックにあり、2 番目のケースでは「インライン」です。

パフォーマンス上の利点はありますか? たとえば、最初のフォームが 1 つしか使用しない場合、2 番目のフォームはバッファーの内容のコピーを 2 つ作成しますか? それとも、純粋にコーディング スタイルの決定ですか? なぜ他の形式よりも 1 つの形式選択するのですか?

スコープ アクセスに違いがあることがわかります。これは、囲んでいるスコープ内の変数は、2 番目の例の「コンテンツの変更」部分で使用できるためですuse。最初の例では、句を使用してそれらを「渡す」必要があります。実際、これがまさに、私が通常 2 番目の形式を選択する理由です。

4

2 に答える 2

2

これで、コードは明確になりました。最初のサンプルでは、​​2回使用した場合を$result示しました(これは良い考えではありませんでした)。

私の主なアイデアは、現在のスコープでを使用する必要がないob_start場合にのみ、コールバックを使用して呼び出すことです。最初の例は次のようになります:$result

ob_start(function($content) {
    // ... modify content ...
    return $content;
}
// ... output stuff ...
ob_end_clean();

この場合、でのジョブ$resultは新しいスコープで行われ、これによりコードがよりクリーンになり(例:を呼び出す)、ジョブの最後にメインスコープからコードを解放する必要ob_start(array($this, 'method'));はありません(Iもちろん、他のことをしていると仮定します)。unset$result

于 2013-02-08T07:08:04.263 に答える
1

ニンスオの正解を少し明確にするだけです。

私の 2 つのコード サンプルでは、​​実際には同じ結果が得られません。実際、コールバックを と組み合わせて使用​​してob_get_clean()もまったく役に立ちません。

これは、バッファのクリーニングまたはフラッシュ時にコールバックが適用されるためです。

ただしob_get_clean()、最初にコンテンツを取得してから、バッファを消去しますつまり、返される内容はコールバックによって返される結果ではなく、コールバックに渡される入力です。

これら 2 つの単純な (そしてハックな) スクリプトを作成して、デモを行いました。

これob_get_clean()は正しい結果を使用しますが、生成しません。

// Tests the use of callbacks with ob_get_clean().
class TestWithGetClean {
    // This variable is set when obcallback is called.
    public $foo = null;

    // The output buffer callback.
    public function obcallback($value) { 
        $this->foo = 'set';
        return $value . '(modified)'; 
    }

    // Main method.
    public function run() {
        ob_start(array($this, 'obcallback'));
        echo 'this is the output', PHP_EOL;
        return ob_get_clean();
    }
}

// Run the test with ob_get_clean().
$t = new TestWithGetClean();
echo $t->run(); // This method returns a value in this test. (But not the correct value!)
echo $t->foo, PHP_EOL;

これを実行した場合の出力は次のとおりです。

これが出力です

設定

テキスト'(modified)'はどこにも表示されません。ただし、インスタンス変数$foo が setであるため、コールバックは確実に呼び出されることに注意してください。ただし、出力は当初の期待どおりではありません。

を使用するこれと比較してくださいob_end_flush()

// Tests the use of callbacks with ob_end_flush().
class TestWithEndFlush {
    // This variable is set when obcallback is called.
    public $foo = null;
    
    // The output buffer callback.
    public function obcallback($value) { 
        $this->foo = 'set';
        return $value . '(modified)' . PHP_EOL; 
    }

    // Main method.
    public function run() {
        ob_start(array($this, 'obcallback'));
        echo 'this is the output', PHP_EOL;
        ob_end_flush();
    }
}

// Run the test with ob_end_flush().
$t2 = new TestWithEndFlush();
$t2->run(); // This method produces output in this test.
echo $t2->foo, PHP_EOL;

これにより、次の出力が生成されます。

これが出力です

(修正)

設定

ただし、出力がクライアントに直接送信されるため、もちろんこれはあまり役に立ちません。そのため、結果をさらに操作することはできません。(たとえば、テキストを Symfony HttpFoundation Component Request オブジェクトにラップします)。

于 2013-02-14T15:30:38.300 に答える