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)
PHP是单线程的...你必须使用你的操作系统来分叉另一个进程.
我知道如何执行此操作的唯一方法是使用exec命令来分叉另一个完整的进程.把你想要的东西放在一个单独的脚本中,在脚本上调用exec,然后立即睡10分钟.如果在10分钟时,该过程仍在运行中杀死它.(你应该通过让命令在后台运行新的php代码,通过命令行获取并从exec命令返回它来获得它的PID).
你想要的是使用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
您可以尝试使用'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,但是:
等等
希望有帮助......