最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • PHP ajax请求返回结果给前端后,在后台继续执行代码的方法

    正文概述 转载于:掘金(郎涯技术)   2021-07-08   225

    1. 问题背景

    在实际项目开发中,遇到一个问题:

    前端通过 Ajax 请求后台 php API 接口,执行多文件的打包下载操作,该请求由于需要更新大量的数据(日志、统计等信息)到数据库且还需要执行较大的磁盘IO操作,导致该请求很耗时间。由于前端页面的更新需要快速响应,因此需要 PHP 快速返回计算结果,然后后台继续执行余下的操作。

    2. 解决方法

    exit() 之后还能继续执行代码的方法有 析构函数 __destruct() 以及 register_shutdown_function() (记日志或者xhprof等性能分析等有一定耗时的代码),但针对 ajax 请求并不能立即返回。

    考虑到 HTTP 请求协议中可以通过 flush() 进行局部内容输出,立即返回请求结果给前端,再将耗时操作继续执行,即通过该技术解决问题。

    3. 源码

    {
        $rs = ['code' => 0, 'msg' => 'ok', 'data' => true];
    
        ob_end_clean();
        ob_start();    
        
        //-----------------------------------------------------------------------------------
        //Windows服务器需要加上这行。
        //echo str_repeat(" ",4096);
        //返回结果给ajax
        echo json_encode($res);
        
        //-----------------------------------------------------------------------------------
        // get the size of the output
        $size = ob_get_length();
        
        // send headers to tell the browser to close the connection
        header("Content-Length: $size");
        header('Connection: close');
        header("HTTP/1.1 200 OK");
        header("Content-Type: application/json;charset=utf-8");
        ob_end_flush();
        if(ob_get_length())
            ob_flush();
        flush();
        
        // yii或yaf默认不会立即输出,加上此句即可(前提是用的fpm)
        if (function_exists("fastcgi_finish_request")) { 
            // 响应完成, 立即返回到前端,关闭连接
        	fastcgi_finish_request(); 
        }
    
         /******** background process starts here ********/
        //在关闭连接后,继续运行php脚本
         ignore_user_abort(true);    
         /******** background process ********/
        //no time limit,不设置超时时间(根据实际情况使用)
         set_time_limit(0); 
         /******** Rest of your code starts here ********/
         //继续运行的代码
         ...
         ...
    

    As of August 2012, all browsers seem to show an all-or-nothing approach to buffering. In other words, while php is operating, no content can be shown.

    In particular this means that the following workarounds listed further down here are ineffective:

    1. ob_flush (), flush () in any combination with other output buffering functions;

    2. changes to php.ini involving setting output_buffer and/or zlib.output_compression to 0 or Off;

    3. setting Apache variables such as "no-gzip" either through apache_setenv () or through entries in .htaccess.

    So, until browsers begin to show buffered content again, the tips listed here are moot.


    起源地 » PHP ajax请求返回结果给前端后,在后台继续执行代码的方法

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元