PHP设置超时的脚本与系统调用,set_time_limit不工作 [英] PHP set timeout for script with system call, set_time_limit not working

查看:124
本文介绍了PHP设置超时的脚本与系统调用,set_time_limit不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个命令行PHP脚本,使用foreach数组的每个成员运行wget请求。这个wget请求有时可能需要很长时间,所以我想要能够设置超时杀死脚本,如果它超过15秒例如。我有PHP的safemode被禁用,并尝试set_time_limit(15)在脚本的早期,但它无限期继续。 更新:感谢Dor指出这是因为set_time_limit()不尊重system()调用。

I have a command-line PHP script that runs a wget request using each member of an array with foreach. This wget request can sometimes take a long time so I want to be able to set a timeout for killing the script if it goes past 15 seconds for example. I have PHP safemode disabled and tried set_time_limit(15) early in the script, however it continues indefinitely. Update: Thanks to Dor for pointing out this is because set_time_limit() does not respect system() calls.

其他方式杀死脚本15秒后执行。但是,我不知道是否可以检查一个脚本在同一时间在一个wget请求的中间运行的时间(do while循环不工作)。可能用一个定时器分配一个进程,并设置它在一定时间后杀死父级?

So I was trying to find other ways to kill the script after 15 seconds of execution. However, I'm not sure if it's possible to check the time a script has been running while it's in the middle of a wget request at the same time (a do while loop did not work). Maybe fork a process with a timer and set it to kill the parent after a set amount of time?

感谢任何提示!

更新:
下面是我的相关代码。 $ url是从命令行传递的,是一个由多个URL组成的数组(对不起初不发布):

Update: Below is my relevant code. $url is passed from the command-line and is an array of multiple URLs (sorry for not posting this initially):

foreach( $url as $key => $value){
    $wget = "wget -r -H -nd -l 999 $value";
    system($wget);
    }


推荐答案

--timeout和time()。

You can use a combination of "--timeout" and time(). Start off by figuring out how much time you have total, and lower the --timeout as your script runs.

例如:

$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);
  }
}

注意:如果不使用-t,

Note: if you don't use -t, wget will try 20 times, each waiting --timeout seconds.

下面是一些使用proc_open / proc_terminate(@Josh的建议)的示例代码:

Here's some example code using proc_open/proc_terminate (@Josh's suggestion):

$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设置超时的脚本与系统调用,set_time_limit不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆