V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
kisshere
V2EX  ›  程序员

php 在 echo 之后是不是就不能执行后续代码了?

  •  
  •   kisshere · 2015-03-23 10:56:29 +08:00 via Android · 6243 次点击
    这是一个创建于 3569 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一个常用的ajax请求json过程:
    <?php
    ...
    echo json_encode($callbackData);
    exit;
    ?>
    现在由于请求这个ajax之后,服务器还要执行一个耗费很长时间的函数longtime(),我就在想能不能在echo json_encode($callbackData);之后执行longtime()这样可以避免用户等待很久的时间,又能继续让服务器执行longtime()函数?
    <?php
    ...
    echo json_encode($callbackData);
    longtime():
    exit;
    ?>
    目前采用的是ajax二次请求的形式,即:
    $.post(targetUrl,{obj:obj},function(){
    $.post(execute_longtime_url)
    })
    服务器端设置set_time_limit(0)和ignore_user_abort,但这样我每次都要请求两次服务器,求高手解答,手机码字不易,谢啦
    6 条回复    2015-03-23 11:21:52 +08:00
    yaxin
        1
    yaxin  
       2015-03-23 11:00:02 +08:00
    消息队列,能解决你的问题
    kisshere
        2
    kisshere  
    OP
       2015-03-23 11:01:28 +08:00 via Android
    @yaxin 大神能详细点吗?
    raincious
        3
    raincious  
       2015-03-23 11:08:11 +08:00   ❤️ 2
    @kisshere

    就是将昂贵的操作交给消息队列。

    比如你可以不在这个PHP程序里处理那个longtime操作,直接输出好给用户,然后请求消息队列来进行处理。

    不过PHP是可以在输出之后仍然继续运行的的,不过具体操作有点Hack。你需要忽略用户的关闭请求,用ignore_user_abort,然后在数据输出之后立即用flush和ob_flush之类来关闭输出缓存,让上层(Apache、Nginx之类)知道你结束响应了,之后你就可以Happy的继续玩你的了。

    但是PHP不太适合执行长时间的任务,Apache的那个线程会被锁死直到释放,注意。

    斗胆拿这段代码供你参考下:
    https://github.com/raincious/facula/blob/master/src/Facula/Base/Prototype/Core/Response.php#L506
    注意ob已经在436行打开过了。
    freefcw
        4
    freefcw  
       2015-03-23 11:20:57 +08:00   ❤️ 1
    优先还是考虑使用消息队列之类的在别的地方处理,主要原因#3说的比较清楚了。对于单线程的php来说,执行这种长时间的任务会影响你的并发,而且也不方便后期的拆解模块。

    如果使用php-fpm的话,可以使用fastcgi_finish_request这个函数,在输出以后继续执行你的php代码,详见

    http://php.net/manual/zh/function.fastcgi-finish-request.php
    simman
        5
    simman  
       2015-03-23 11:21:49 +08:00
    肯定要用队列了,主要是异步问题。
    cute
        6
    cute  
       2015-03-23 11:21:52 +08:00   ❤️ 1
    php-fpm可以这样,还是建议使用服务端异步队列

    fastcgi_finish_request();
    longtime();
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2892 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 13:43 · PVG 21:43 · LAX 05:43 · JFK 08:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.