PHP后台进程

我试图做一个PHP脚本,我已经完成脚本,但它需要10分钟来完成它旨在执行的过程。 这不是一个问题,但我想我必须保持页面加载所有这些烦人的。 我能否拥有它,以便我启动该进程,然后在10分钟后回来,并查看它生成的日志文件?

那么你可以使用“ ignore_user_abort (true)”

所以脚本将继续工作(留意脚本持续时间,可能会添加“ set_time_limit (0)”)

但是这里有一个警告:你不能用这两行来停止脚本:

ignore_user_abort(true); set_time_limit(0); 

除了你可以直接访问服务器并杀死那里的进程! (在那里,做了一个无休止的循环,一遍又一遍地调用自己,使服务器来到一个尖锐的停止,在…喊)

听起来你应该有一个队列和一个外部脚本来处理队列。

例如,你的PHP脚本应该input一个数据库表并立即返回。 然后,每分钟运行一个cron检查队列并为每个作业分配一个进程。

这里的优点是你不会locking一个Apache线程10分钟。

在windows下这种过程我有很多问题。 我的情况有点不同,我不在意“脚本”的反应 – 我想让脚本启动,并允许其他页面请求在忙于工作时通过。

因为某些原因; 我有问题,要么悬挂其他请求或约60秒后超时(Apache和PHP都设置为超时约20分钟后); 事实也certificate,无论如何5分钟后(默认情况下),Firefox会超时,所以在那之后你不能通过浏览器知道怎么回事,而不用改变Firefox的设置。

我结束了使用过程打开和处理closures方法来打开一个PHP在cli模式,如下所示:

pclose(popen("start php myscript.php", "r"));

这将(使用开始)打开PHP进程,然后杀死启动过程,让PHP运行不pipe需要多长时间 – 再次,你需要杀死进程手动closures它。 它不需要你设置任何超时,你可以让当前的页面继续,并输出更多的细节。

唯一的问题是,如果你需要发送脚本的任何数据,你要么通过另一个来源或沿“命令行”作为parameter passing; 这并不安全。

为我们所需要的工作很好,并确保脚本始终启动,并允许运行而不会中断。

这可能也有帮助: PHP中的asynchronousshell exec

我认为shell_exec命令是你正在寻找的。

但是,在安全模式下是禁用的。

有关它的PHP手册文章在这里: http : //php.net/shell_exec

这里有一篇关于它的文章: http : //nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/

您可以使用ignore_user_abort() – 即使您closures浏览器或转到其他页面,脚本仍将继续运行。

还有另外一个选项,你可以使用,运行脚本CLI …它将在后台运行,你甚至可以运行它作为一个cronjob如果你想要的。

例如

 > #!/usr/bin/php -q <?php //process logs ?> 

这可以设置为一个cronjob,并将执行没有时间限制….这个例子是基于unix的操作系统。

仅供参考我有一个php脚本运行一个无限循环,做一些处理,并已运行在过去3个月不停。

想想Gearman

Gearman是一个通用的应用程序框架,用于将工作迁移到多台机器或进程。 它允许应用程序并行完成任务,负载平衡处理以及在语言之间调用函数。 该框架可用于从高可用性网站到传输数据库复制事件的各种应用程序。

这个扩展提供了写Gearman客户端和工作者的类。 – 源代码php手册

Gearman官方网站

除了bastiando的答案,你可以结合使用ignore_user_abort(true); 与一个cUrl请求

伪造一个请求stream产,设置一个低的CURLOPT_TIMEOUT_MS并在连接closures后继续处理:

 function async_curl($background_process=''){ //-------------get curl contents---------------- $ch = curl_init($background_process); curl_setopt_array($ch, array( CURLOPT_HEADER => 0, CURLOPT_RETURNTRANSFER =>true, CURLOPT_NOSIGNAL => 1, //to timeout immediately if the value is < 1000 ms CURLOPT_TIMEOUT_MS => 50, //The maximum number of mseconds to allow cURL functions to execute CURLOPT_VERBOSE => 1, CURLOPT_HEADER => 1 )); $out = curl_exec($ch); //-------------parse curl contents---------------- //$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); //$header = substr($out, 0, $header_size); //$body = substr($out, $header_size); curl_close($ch); return true; } async_curl('http://example.com/background_process_1.php'); 

NB

如果你希望cURL在不到一秒的时间内超时,你可以使用CURLOPT_TIMEOUT_MS,虽然在“类Unix系统”上有一个bug /“function”,导致libcurl立即超时,如果该值<1000毫秒,curl错误(28):达到超时“。 这种行为的解释是:

[…]

解决方法是使用CURLOPT_NOSIGNAL禁用信号

利弊

  • 无需切换方法(兼容的Windows和Linux)
  • 无需通过头和缓冲区实现连接处理(独立于浏览器和PHP版本)

缺点

  • 需要curl延伸

资源

ZUK。

我很确定这将工作:

 <?php pclose(popen('php /path/to/file/server.php &')); echo "Server started. [OK]"; ?> 

'&'是重要的。 它告诉shell不要等待进程退出。

你也可以使用这个代码在你的PHP(如“bastiandoeen”说)

 ignore_user_abort(true); set_time_limit(0); 

在你的服务器停止命令:

 <?php $output; exec('ps aux | grep -ie /path/to/file/server.php | awk \'{print $2}\' | xargs kill -9 ', $output); echo "Server stopped. [OK]"; ?>