限制函数或命令 PHP 的执行时间

Posted

技术标签:

【中文标题】限制函数或命令 PHP 的执行时间【英文标题】:Limit execution time of an function or command PHP 【发布时间】:2010-11-13 16:09:03 【问题描述】:

您好,是否可以仅对命令或仅对函数设置时间限制,例如:

function doSomething()

    //..code here..

    function1();

    //.. some code here..


我只想为function1设置时间限制。

退出 set_time_limit 但我认为这将时间限制设置为整个脚本。 有人有什么想法吗?

【问题讨论】:

如果在function1仍在运行时计时器到期,您希望发生什么? 【参考方案1】:
$endtime=time()+10;

while(time()!=$endtime)

    echo ".";

【讨论】:

【参考方案2】:

我使用 exec 运行从外部应用程序生成导出的 shellscript。如果脚本运行时间过长,就会达到 max_execution_time 并且用户永远不会知道发生了什么。对此类功能的限制将帮助我确定 end 是否接近并发送一些用户友好的错误。

【讨论】:

【参考方案3】:

不,这是不可能的:max_execution_time 被用作安全措施,以避免错误的脚本(如无限循环)破坏服务器;但它并不打算在功能单元的基础上工作。

而且最终导致致命错误的事实对用户来说绝对不是一件好事......

【讨论】:

【参考方案4】:

set_time_limit() 确实全局运行,但可以在本地重置。

设置允许脚本运行的秒数。如果达到这一点, 该脚本返回一个致命错误。默认限制为 30 秒,或者,如果它 存在,在 php.ini 中定义的 max_execution_time 值。

调用时,set_time_limit() 从零重新启动超时计数器。在 换句话说,如果超时是默认的 30 秒和 25 秒 进入脚本执行一个调用,如 set_time_limit(20),脚本 在超时之前将运行总共 45 秒。

我没有测试过,但是你可以在本地设置,离开时重置

<?php
set_time_limit(0);  // global setting

function doStuff()

    set_time_limit(10);   // limit this function
    //  stuff
    set_time_limit(10);   // give ourselves another 10 seconds if we want
    //  stuff
    set_time_limit(0);    // the rest of the file can run forever


// ....
sleep(900);
// ....
doStuff();  // only has 10 secs to run
// ....
sleep(900);
// ....

set_time_limit() ... 在确定最大时间时,不包括在脚本执行之外发生的活动所花费的任何时间,例如使用 system() 的系统调用、流操作、数据库查询等脚本一直在运行。这在测量时间是真实的 Windows 上是不正确的。

【讨论】:

非常好!谢谢!但如果不满足时间标准,它会返回一个致命错误。有没有办法避免这种情况。 无法停止致命错误 - 因为这就是超时。如果您想做其他事情,那么您将必须更全面地定义您正在做的事情,并设计一个可以按要求执行的系统。如果您正在执行耗时过长的数据库查询,我会尝试改进查询(和底层数据库)以加快它们的速度,而不是尝试修复原始问题之外的某些问题。 谢谢你帮我找到了正确的东西。我想我在看的是 max_input_time 你知道如果没有达到最后期限,它是否也会返回致命错误? php.ini 配置 max_input_time 是脚本启动、解析输入数据(如 POST、GET 和文件上传)所需的时间。这些任务必须在您的任何 PHP 代码运行之前完成。 不是很好的解决方案,导致它对所有脚本全局影响,所以最好使用超时!【参考方案5】:

如果您希望 function1 在时间限制结束时返回,您需要自己编写代码。

function doStuff($seconds)

    $finish=time()+$seconds;

    $done=false;
    $timeout=false;

    while (!$done && !$timeout)
    
        //do stuff here, set $done to true if you complete

        //out of time?
        $timeout=time() >= $finish;

    

    return $done; //let caller know if we completed

当然,您所做的“事情”需要反复进行,以便您可以继续检查您的已用时间并在必要时退出。

如果您希望超时执行任意函数并将控制权返回给您,则不支持。如果您确实需要这样做,请将其设计为一个单独的流程。然后,如果它看起来花费的时间太长,您可以关闭该过程。

【讨论】:

谢谢你的答案,但看看这个 acenario 函数 doStuff($seconds) $finish=time()+$seconds; $完成=假; $超时=假; while (!$done && !$timeout) //在这里做一些事情,如果你完成 //out of time? 将 $done 设置为 true? $结果 = 另一个函数();这个函数是一个标准的 php 函数,不能修改,在我的情况下执行起来需要太多时间。 $timeout=time() >= $finish; 返回$完成; //让调用者知道我们是否完成了 谢谢你的答案,但看看这个 acenario function doStuff($seconds) $finish=time()+$seconds; $完成=假; $超时=假; while (!$done &amp;&amp; !$timeout) //在这里做一些事情,如果你完成 //out of time? 将 $done 设置为 true? $结果 = 另一个函数();这个函数是一个标准的 php 函数,不能修改,在我的情况下执行起来需要太多时间。 $timeout=time() &gt;= $finish; 返回$完成; //让调用者知道我们是否完成了 您不能让任意函数在指定时间后退出。如果您确实需要这样做,请将其设计为一个单独的流程。然后,如果它似乎花费的时间太长,您可以关闭该过程。 嗯,你基本上可以用任何其他语言来做到这一点。 PHP 的另一个光荣“特性”... 没有为我工作 php v7.2.3 ,如果“在这里做东西”需要太多时间,其他部分没有触发,直到“做”不会结束所有冻结!无效的解决方案(【参考方案6】:

我不认为这是可能的,但你为什么要这样做?如果脚本被打断,我可能不希望你想要它。这应该更像是对自己的一种保护(以防万一你上传一个无限循环或需要几个小时的东西),但如果你的脚本需要很多时间,你应该给它所需的时间,或者更改脚本以便它运行得更快(对于某些 crons 可以花一些时间,但如果一个正常调用的脚本经常花费超过默认时间限制,您可能会面临一些严重的性能问题)

【讨论】:

假设我的脚本从数据库中获取数据,并且对于每一行,它都会尝试对该行做一些事情,比如 doSomething(row) 但有时这可能会耗费太多时间。所以我需要像当这个 doSomething 在 5 分钟内没有完成时才能继续另一行。如果我能以某种方式制作一个类似的函数: function doSomething() //code here return results;但是如果这个函数不能在5分钟内完成就返回false为例! 嗯好吧,在那种情况下坚持保罗迪克森的答案

以上是关于限制函数或命令 PHP 的执行时间的主要内容,如果未能解决你的问题,请参考以下文章

“真实”执行时间限制

php代码审计5审计命令执行漏洞

PHP修改脚本最大执行时间和最大内存限制

睡眠时间是不是计入执行时间限制?

如何优化 sql 查询以避免在没有 php.ini 或设置时间限制的情况下执行最长时间 [关闭]

php脚本执行时间限制