繁体   English   中英

浏览器窗口中的PHP回调

[英]PHP callback in browser window

我正在尝试学习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秒出现一个新行,但在浏览器窗口中我必须等到代码完成执行,然后才能看到结果。

所以问题是,为什么它在控制台中工作,而不是在浏览器窗口中?

这很可能是因为输出缓冲。

输出缓冲是PHP中的一种机制,它将输出保存在内存中,直到稍后调用flush缓冲区(当脚本关闭时也会自动发生)。

输出缓冲允许您打印脚本内部的内容,并在打印内容后提供对HTTP标头的更改。 通常,一旦打印内容并将其发送到apache(然后将其发送回客户端),您就无法再修改HTTP标头。 使用输出缓冲,PHP会将此输出存储在内存中,并且在您告知之前不会将其传递给apache。

您应该可以通过以下四种方式之一来实现此目的:

  • ob_end_clean位于PHP脚本的最顶层,用于禁用输出缓冲
  • 在php.ini中禁用output_buffering
  • 在php.ini中启用implicit_flush (不推荐使用,因为它使output_buffering无意义
  • print / echo语句之后调用ob_flush

注意:输出缓冲还有其他非常合理的用途,例如模板 - 但这在这里并不重要。

有了这个说

这不一定适合每个人。 默认情况下某些浏览器和配置中的其他浏览器在关闭连接并收到所有HTML内容之前不会开始加载页面。 如果您希望今天在大多数浏览器中都能使用它 - 您可能最好将AJAX调用回服务器。

编辑:要判断output_buffering是否打开, print ob_get_level()的简单调用将告诉您。 如果打印数字> 0,则output_buffering是罪魁祸首。

在控制台中运行的所有脚本都会实时显示。 这就是它在控制台而不是在浏览器中工作的原因。 你有一些选择 - 经常刷新(不是一个非常好的解决方案,因为大多数浏览器都不会对此感到高兴),从那里使用ob_start或使用ajax,这是我认为最安全的赌注。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM