ref*_*xiv 3 php linux windows command-line
我有一个命令行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);
}
Run Code Online (Sandbox Code Playgroud)
--timeout除了之外,请尝试使用wget命令行参数set_time_limit().
请记住set_time_limit(15) 从零开始重新启动超时计数器,所以不要在循环内调用它(为了您的目的)
来自man wget:
--timeout =秒
将网络超时设置为秒秒.这相当于同时指定--dns-timeout, - connect-timeout和--read-timeout.
在与网络交互时,Wget可以检查超时并在操作时间过长时中止操作.这可以防止像挂起读取和无限连接之类的异常.默认情况下启用的唯一超时是900秒读取超时.将超时设置为0会完全禁用它.除非您知道自己在做什么,否则最好不要更改默认的超时设置.
所有与超时相关的选项都接受十进制值以及亚秒值.例如,0.1秒是超时的合法(虽然不明智)选择.亚秒超时对于检查服务器响应时间或测试网络延迟非常有用.
编辑:好的.我明白你现在在做什么.您应该做的是使用proc_open代替system,并使用time()函数检查时间,如果wget tskes太长则调用proc_terminate.
您可以结合使用“--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<br>";
system($wget);
} else {
print("timed out!");
exit(0);
}
}
Run Code Online (Sandbox Code Playgroud)
注意:如果不使用 -t,wget 将尝试 20 次,每次等待 --timeout 秒。
下面是一些使用 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");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5729 次 |
| 最近记录: |