代码之家  ›  专栏  ›  技术社区  ›  Sampson

放弃PHP中的长进程(但让它们完成)

  •  4
  • Sampson  · 技术社区  · 15 年前

    我有一个HTML表单,它提交到启动脚本的PHP页面。脚本运行时间从3秒到30秒不等-用户不需要在周围完成此脚本。

    是否可以启动一个PHP脚本,立即向用户(或其他人)打印“谢谢”,让他们在脚本继续工作时愉快地继续工作?

    在我的特殊情况下,我将表单数据发送到一个PHP脚本,然后将数据发布到许多其他位置。目前,等待所有职位的成功并不符合我的兴趣。我只想让脚本运行,允许用户去做他们想做的任何事情,就是这样。

    6 回复  |  直到 15 年前
        1
  •  2
  •   Daniel Von Fange    15 年前

    例如,将长期工作放在另一个PHP脚本中

    背景:PHP:

    sleep(10);
    file_put_contents('foo.txt',mktime());
    

    前缀

    $unused_but_required = array();
    proc_close(proc_open ("php background.php &", array(), $unused_but_required));
    echo("Done);
    

    您将立即看到“完成”,文件将在10秒后写入。

    我认为proc-close是有效的,因为我们没有给proc-open任何管道,也没有文件描述符。

        2
  •  1
  •   Pim Jager    15 年前

    在脚本中,可以设置:

    <?php
     ignore_user_abort(true);
    

    这样,当用户离开页面时脚本就不会终止。但是,在结合这一点时要非常小心

     set_time_limit(0);
    

    从那时起,脚本就可以永远执行。

        3
  •  1
  •   troelskn    15 年前

    你可以使用 set_time_limit ignore_user_abort ,但一般来说,我建议您将作业放入队列中,并使用异步脚本来处理它。这是一个简单耐用的设计。

        4
  •  0
  •   clawr    15 年前

    你可以试试 flush 以及相关的输出缓冲区功能,将缓冲区中的内容立即发送到浏览器:

        5
  •  0
  •   John Ellinwood    15 年前

    在pcntl_fork()周围有一个api包装器调用 php_fork .

    但是,这个问题是关于 Daily WTF …不要用玻璃瓶砸钉子。

        6
  •  0
  •   Sampson    15 年前

    我以以下几点结束。

    <?php
    
      // Ignore User-Requests to Abort
      ignore_user_abort(true);
      // Maximum Execution Time In Seconds
      set_time_limit(30);
    
      header("Content-Length: 0");
      flush();
    
      /*
    
        Loooooooong process
    
      */
    
    ?>