我有一个命令行PHP脚本,使用foreach使用数组的每个成员运行wget请求.这个wget请求有时可能需要很长时间,因此我希望能够设置超时以杀死脚本(例如,如果超过15秒).我已禁用PHP安全模式并在脚本的早期尝试了set_time_limit(15),但它会无限期地继续.更新:感谢Dor指出这是因为set_time_limit()不尊重system()调用.
所以我试图在执行15秒后找到其他方法来杀死脚本.但是,我不确定是否可以检查脚本在同时处于wget请求中间时运行的时间(while循环不起作用).也许用一个定时器分叉一个进程并设置它在一段时间后杀死父进程?
谢谢你的任何提示!
更新:
以下是我的相关代码. $url是从命令行传递的,是一个包含多个URL的数组(对不起,最初不发布):
foreach( $url as $key => $value){
$wget = "wget -r -H -nd -l 999 $value";
system($wget);
}
解决方法:
您可以使用“–timeout”和time()的组合.首先确定总共有多少时间,然后在脚本运行时降低–timeout.
例如:
$endtime = time()+15;
foreach( $url as $key => $value){
$timeleft = $endtime - time();
if($timeleft > 0) {
$wget = "wget -t 1 --timeout $timeleft $otherwgetflags $value";
print "running $wget
";
system($wget);
} else {
print("timed out!");
exit(0);
}
}
注意:如果你不使用-t,wget将尝试20次,每次等待 – 超时秒.
这是使用proc_open / proc_terminate的一些示例代码(@Josh的建议):
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$pipes = array();
$endtime = time()+15;
foreach( $url as $key => $value){
$wget = "wget $otherwgetflags $value";
print "running $wget\n";
$process = proc_open($wget, $descriptorspec, $pipes);
if (is_resource($process)) {
do {
$timeleft = $endtime - time();
$read = array($pipes[1]);
stream_select($read, $write = NULL, $exeptions = NULL, $timeleft, NULL);
if(!empty($read)) {
$stdout = fread($pipes[1], 8192);
print("wget said--$stdout--\n");
}
} while(!feof($pipes[1]) && $timeleft > 0);
if($timeleft <= 0) {
print("timed out\n");
proc_terminate($process);
exit(0);
}
} else {
print("proc_open failed\n");
}
}
标签:php,linux,command-line,windows
来源: https://codeday.me/bug/20190714/1457076.html