超时PHP中的一个函数

Mo3*_*o3z 21 php foreach timeout function

有没有办法超时功能?我有10分钟的时间来完成一份工作.这个工作包括一个for循环,这是一个例子:

<?php
foreach($arr as $key => $value){
   some_function($key, $value); //This function does SSH and SFTP stuff
}
?>
Run Code Online (Sandbox Code Playgroud)

$ arr有15个元素,some_function()有时可能需要1分钟以上.事实上,一旦它被绞死了5分钟.

有没有办法可以超时函数调用并继续使用$ arr中的下一个元素?

谢谢!!

Mik*_*e B 18

这取决于您的实施.PHP中99%的函数都是阻塞的.在当前函数完成之前,意义处理将不会继续.但是,如果函数包含循环,则可以添加自己的代码,以在满足某个条件后中断循环.

像这样的东西:

foreach ($array as $value) {
  perform_task($value);
}

function perform_task($value) {
  $start_time = time();

  while(true) {
    if ((time() - $start_time) > 300) {
      return false; // timeout, function took longer than 300 seconds
    }
    // Other processing
  }
}
Run Code Online (Sandbox Code Playgroud)

另一个不可能中断处理的例子:

foreach ($array as $value) {
  perform_task($value);
}

function perform_task($value) {
    // preg_replace is a blocking function
    // There's no way to break out of it after a certain amount of time.
    return preg_replace('/pattern/', 'replace', $value);
}
Run Code Online (Sandbox Code Playgroud)


Ray*_*Ray 9

PHP是单线程的...你必须使用你的操作系统来分叉另一个进程.

我知道如何执行此操作的唯一方法是使用exec命令来分叉另一个完整的进程.把你想要的东西放在一个单独的脚本中,在脚本上调用exec,然后立即睡10分钟.如果在10分钟时,该过程仍在运行中杀死它.(你应该通过让命令在后台运行新的php代码,通过命令行获取并从exec命令返回它来获得它的PID).


Jac*_*ues 8

你想要的是使用pcntl_alarm函数,它将在超时时触发SIGALRM信号.例如:

// 10 minutes
pcntl_alarm( 600 );
pcntl_signal(SIGALRM, function() { print( "Timed-out!\n" ); exit( 0 ); });
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅PHP手册:http://php.net/manual/en/function.pcntl-alarm.php

  • 这是一个完整的实现:https://gist.github.com/avalanche123/3085581 (3认同)

aur*_*ora 5

您可以尝试使用'curl'来实现它.Curl是 - 来自PHP - 主要用于做HTTP/FTP的东西,但它支持更多的协议,包括ssh/sftp.我从未使用curl做过与ssh/sftp相关的事情,所以我不能给出任何额外的建议,但你应该能够在stackoverflow或其他地方找到更多信息.

您可以使用选项"CURLOPT_TIMEOUT"来配置请求的超时(还有一个选项"CURLOPT_CONNECTTIMEOUT").您甚至可以以毫秒分辨率(CURLOPT_TIMEOUT_MS/CURLOPT_CONNECTTIMEOUT_MS)指定超时.

无论如何:对于一个cronjob,我建议使用一个额外的"锁定文件",你的脚本在它启动时写入并在它完成运行时删除.您可以在脚本中检查此锁定文件,因此如果cron 在上次运行完成之前触发了您的脚本,您可以直接退出脚本而无需进一步操作.这可以确保您的脚本不会多次并行执行.

您还可以在PHP文档中找到有关CURL选项和CURL本身的更多信息:

你必须确保你安装的libcurl和/或curl for php支持SSH/SFTP,但是:

等等

希望有帮助......