0

PHP コールバックについて学習しようとしています。phpriot.comの例を使用しています。

---------------this code-----------------------------
 // this function simulates downloading data from a site
    function downloadFromSites($sites, $callback = null)
    {
        $ret = array();

        foreach ($sites as $site) {
            sleep(2);

            $data = 'downloaded data here';

            // check if the callback is valid
            if (is_callable($callback)) {
                // callback is valid - call it with given arguments
                call_user_func($callback, $site, $data);
            }

            // write the data for this site to return array
            $ret[] = array(
                'site' => $site,
                'data' => $data
            );
        }

        return $ret;
    }

    // define a fictional class used for the callback
    class MyClass
    {
        // this is the callback method
        public static function downloadComplete($site, $data)
        {
            echo sprintf("Finished downloading from %s\n", $site);
        }
    }

    // imaginary list of sites to download from
    $sites = array(
        'http://www.example1.com',
        'http://www.example2.com'
        // more sites...
    );

    // start downloading and store the return data
    downloadFromSites($sites, array('MyClass', 'downloadComplete'));

    // we don't need to loop over the return data
    // now since the callback handles that instead

このコードを実行すると、最後ではなく、各サイトが完了するたびに「ダウンロードが完了しました」というメッセージが表示されることがわかります。


したがって、このコードをコンソールで実行すると問題なく動作します。2 秒ごとに新しい行が表示されますが、ブラウザ ウィンドウではコードの実行が終了するまで待たなければならず、その後で結果が表示されます。

問題は、ブラウザ ウィンドウではなくコンソールで機能するのはなぜですか?

4

2 に答える 2

2

これは、出力バッファリングが原因である可能性があります。

出力バッファリングは、後でバッファが呼び出されるまで出力をメモリに保持する PHP のメカニズムですflush(スクリプトがシャットダウンしたときにも自動的に行われます)。

出力バッファリングを使用すると、スクリプト内のコンテンツを出力し、コンテンツの出力後に HTTP ヘッダーに変更を加えることができます。通常、コンテンツを印刷して Apache に送信すると (Apache はそれをクライアントに送り返します)、HTTP ヘッダーを変更することはできなくなります。出力バッファリングを使用すると、PHP はこの出力をメモリに保存し、ユーザーが指示するまで Apache に渡しません。

これは、次の 4 つの方法のいずれかで機能させることができます。

  • ob_end_clean出力バッファリングを無効にする PHP スクリプトの一番上に
  • output_bufferingphp.ini で無効にする
  • implicit_flushphp.ini で有効にします (無意味になるためお勧めしませんoutput_buffering)
  • /ステートメントob_flushの後に呼び出しますprintecho

注:テンプレート化など、出力バッファリングには他にも非常に正当な用途がありますが、ここでは重要ではありません。

そうは言っても

これは必ずしもすべての人に当てはまるわけではありません。一部のブラウザはデフォルトで、その他は設定により、接続が閉じられ、すべての HTML コンテンツが受信されるまで、ページのロードを開始しません。これを今日のほとんどすべてのブラウザーで機能させたい場合は、サーバーに AJAX 呼び出しを行う方がよいかもしれません。

編集:がオンになっているかどうかを確認するoutput_bufferingには、 を呼び出すだけでprint ob_get_level()わかります。それが数字> 0を出力する場合、それoutput_bufferingが原因です。

于 2013-02-05T13:30:44.323 に答える
0

コンソールで実行されたすべてのスクリプトがリアルタイムで表示されます。これが、ブラウザーではなくコンソールで機能する理由です。いくつかのオプションがあります-頻繁にフラッシュする(ほとんどのブラウザーはこれに満足しないため、本当に良い解決策ではありません)、そこからob_startを使用するか、最も安全な賭けであるajaxを使用します。

于 2013-02-05T13:37:11.630 に答える