题
我在尝试做一个PHP script,我有脚本完成,但它需要等10分钟完成的进程是设计来做。这不是一个问题,但是我想我有保持该网页载有这一时间,这是令人讨厌。我可以把它让我开始的进程,然后回来的10分钟以后,只是查看日志文件,它已经产生?
解决方案
好吧,你可以使用<!> << ignore_user_abort (真)<> QUOT;!
因此脚本将继续工作(密切注意脚本持续时间,也许添加<!>; set_time_limit (0)<!> quot;)
但是这里有一个警告:你将无法使用这两行停止脚本:
ignore_user_abort(true);
set_time_limit(0);
除了你可以直接访问服务器并杀死那里的进程! (在那里,做了一个无休止的循环,一遍又一遍地呼唤自己,让服务器突然停下来,大声喊叫......)
其他提示
听起来你应该有一个队列和一个外部脚本来处理队列。
例如,您的PHP脚本应该将一个条目放入数据库表并立即返回。然后,每分钟运行一次的cron检查队列并为每个作业分叉一个进程。
这里的优点是你不会将apache线程锁定10分钟。
我在windows下遇到了很多关于这种过程的问题;我的情况有点不同,因为我不关心<!>“脚本<!>”的响应 - 我希望脚本启动并允许其他页面请求在忙碌的工作时通过
出于某种原因;我有问题要么挂掉其他请求,要么在大约60秒后超时(apache和php都会在大约20分钟后超时);事实证明firefox在5分钟后(默认情况下)会超时,所以在那之后你无法在不改变firefox设置的情况下通过浏览器知道发生了什么。
我最终使用进程打开并处理close方法在cli模式下打开php,如下所示:
pclose(popen("start php myscript.php", "r"));
这将(使用start)打开php进程然后终止启动进程让php运行不管它需要多长时间 - 再次你需要杀死进程来手动关闭它。它不需要您设置任何超时,您可以让当前调用它的页面继续并输出更多详细信息。
唯一的问题是,如果您需要向脚本发送任何数据,您可以通过其他来源执行此操作,也可以沿着<!> quot;命令行<!>传递它;作为参数;这不太安全。
很好地完成了我们所需要的工作,并确保脚本始终启动并允许其运行而不会中断。
这可能也有帮助,还有: PHP中的异步shell执行程序
我认为shell_exec命令是什么你是在寻找。
然而,禁止在安全模式。
PHP手册的条约就是在这里: http://php.net/shell_exec
有一篇文章关于: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/
您可以使用另一个选项,运行脚本CLI ...它将在后台运行,您甚至可以根据需要将其作为cronjob运行。
例如
> #!/usr/bin/php -q
<?php
//process logs
?>
这可以设置为cronjob并且将在没有时间限制的情况下执行....这个示例适用于基于unix的操作系统。
FYI 我有一个运行了无限循环的PHP脚本,它进行了一些处理,并且在过去3个月内一直在运行。
您可以使用 ignore_user_abort()
- 即使您关闭,脚本也会继续运行您的浏览器或转到其他页面。
此外,bastiandoeen的答案你可以结合 ignore_user_abort(true);
与 卷曲的请求.
假的请求堕胎设置一个低 CURLOPT_TIMEOUT_MS
并保持处理的连接之后关闭:
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的
如果你要的卷曲超时在不到一秒,你可以使用 CURLOPT_TIMEOUT_MS,虽然有一个错误/"要素"上的"Unix-like 系统",原因libcurl超时立即如果价值是 < 1000毫错误"的卷曲的错误(28):超时达成".的 解释这种行为是:
[...]
该方案是禁用的信号使用CURLOPT_NOSIGNAL
优点
- 不需要转换的方法(兼容windows和linux)
- 没有必要实现连接处理通过标题和缓冲区(独立于浏览器和PHP version)
弊
- 需要扩展卷曲
资源
ZUK。
我很确定这会奏效:
<?php
pclose(popen('php /path/to/file/server.php &'));
echo "Server started. [OK]";
?>
'<!> amp;'很重要它告诉shell不要等待进程退出。
此外,您可以在您的PHP中使用此代码(作为<!> quot; 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]";
?>
在任何输出之前调用StartBuffer(),在希望客户端关闭连接时调用EndBuffer()。调用EndBuffer()之后的代码将在没有客户端连接的服务器上执行。
private function StartBuffer(){ @ini_set('zlib.output_compression',0); @ini_set('implicit_flush',1); @ob_end_clean(); @set_time_limit(0); @ob_implicit_flush(1); @ob_start(); } private function EndBuffer(){ $size = ob_get_length(); header("Content-Length: $size"); header('Connection: close'); ob_flush();ob_implicit_flush(1); }