想知道是否有一个was,以防止在部分代码开始处理时发生php超时。
让我解释一下:
我有一个脚本,它的执行时间太长,甚至无法使用
ini_set('max_execution_time', 0);
set_time_limit(0);
代码的构建允许它超时并在原来的位置重新启动,但我有两行代码需要一起执行才能实现
$email->save();
$this->_setDoneWebsiteId($user['id'], $websiteId);
php中有没有一种方法可以告诉它,即使调用了超时,它也必须完成这两项操作?
在我写这篇文章的时候,我有一个想法,我可以使用120秒之外的时间来启动计时器,如果离暂停还有不到20秒的时间,我只想知道我是否错过了什么。
感谢您的投入。
如果您的代码不同步,并且某些任务需要超过100秒,则无法检查执行时间。
我只看到一个真正的HACK(小心,在控制台中用php-f测试它是否能够杀死进程):
<?php
// Any preparations here
register_shutdown_function(function(){
if (error_get_last()) { // There was timeout exceeded error
// Call the rest of your system
// But note: you have no stack, no context, no valid previous frame - nothing!
}
});
您可以做的一件事是使用DATE时间功能来监控您的平均执行时间。(假设你有一个循环,每次执行都会积累起来)。
如果平均时间比你剩下的时间长(你会根据你的最大执行时间计算已经花了多少时间),你会触发重新启动,让它从停止的地方恢复。
然而,如果您遇到超时,您可能希望找到提高代码效率的方法。
不,您不能中止超时处理程序,但我想说,如果您不解析一些巨大的东西,20秒是相当长的时间。但是,您可以执行以下操作:
- 获取执行开始的时间(控制器开头的
$start = $_SERVER['REQUEST_TIME']
或仅$start = microtime(true);
) - 在运行
$email->save()
或暂停/跳过代码(如有必要)之前执行时间小于100秒的资产。这和if (microtime(true) - $start < 100) { $email->save()... }
一样简单。不过,您希望对此有更多的抽象性 - (如有必要)在两个方法都运行后检查执行时间,如果超时则停止执行
这将需要将time_limit
设置为大值,甚至关闭并进行繁琐的工作,以防止执行时间过长。在大多数情况下,超时是你的朋友告诉你的工作花费了太多时间,你应该重新思考你的架构和内部流程;如果您的时间超过120秒,您可能希望将这项工作放在守护进程上。
感谢您的输入,因为我认为计时器解决方案是最好的方法。
我最终做的是以下内容,这不是实际的代码,因为它太长了,无法做出一个好的答案,而只是一般的想法。
ini_set('max_execution_time', 180);
set_time_limit(180);
$startTime = date('U'); //give me the current timestamps
while(true){
//gather all the data i need for the email
//I know its overkill to break the loop with 1 min remaining
//but i realy dont want to take chances
if(date('U') < ($startTime+120)){
$email->save();
$this->_setDoneWebsiteId($user['id'], $websiteId);
}else{
return false
}
}
我无法使用测量每个周期的平均时间的想法,因为它变化太大了。
我本可以让代码更高效,但它的周期数是基于框架中用户和网站的数量。它应该足够大,无论如何都需要多次运行才能完成。
我必须做一些研究来理解register_shutdown_function,但我会研究一下
再次感谢!