PHP max_execution time 是不是在每个函数调用上重置?

Posted

技术标签:

【中文标题】PHP max_execution time 是不是在每个函数调用上重置?【英文标题】:Does PHP max_execution time resets on each function call?PHP max_execution time 是否在每个函数调用上重置? 【发布时间】:2020-07-14 03:29:59 【问题描述】:

我今天遇到了这个问题。我正在编写一个函数来运行 cron 作业以生成订单的 pdf,将其保存在数据库中并将邮件作为附件发送。我从数据库中获取所有订单,并在循环中运行它来为每个订单生成、存储和发送邮件。这项工作在本地很好,可能是因为数据较少,但在部署后,我们得到了 max_execution_time of 30 seconds exceeded 错误。错误指向我们用来生成 pdf(fpdf) 的库中的一个文件。 由于无法实时获取数据进行测试,因此我在循环中运行了 pdf 生成函数。作为,

for ($i = 0; $i < 300; ++$i) 
    $start = microtime(true);
    $pdf = $page->createNewPdf();                
    echo $i;
    echo '<br />';
    echo base64_encode($pdf);
    $end = microtime(true);
    echo 'Diff '.($end - $start);

这里的差异平均为 0.24374079704285。 在生成 126 个有时 127 个 pdf 文件后,我得到了 max_execution_time exceeded 错误。 只是为了测试,我调用了从循环内发送电子邮件的函数

             for ($i = 0; $i < 200; ++$i) 
                $start = microtime(true);
                $pdf = $page->createNewPdf();
                $page->sendMail(100, $pdf);

                echo $i;
                echo '<br />';
                echo base64_encode($pdf);
                echo '<br/>';
                $end = microtime(true);
                echo 'Diff '.($end - $start);
            

这里的区别是 6.122..... 重点是 我在 30 秒后没有收到超出 max_execution_time 的错误,但在大约 7 到 8 分钟后我想知道为什么? php版本为7.1.33,服务器为Aache。

如果 max_execution_time 设置为 30,则意味着对服务器的请求应在 30 秒限制内发送响应,还是每次在请求中调用函数时都会重置执行时间,createNewPdf() = 30s, sendMail () = 30 秒。 我仍然收到大约 7-8 分钟的错误。为什么?

没有调用 sendMail() 的错误 致命错误:第 1564 行的 ...../fpdf/tfpdf.php 中超过了 30 秒的最大执行时间 调用 senMail() 时出错 致命错误:第 1564 行的 ...../lib/fpdf/tfpdf.php 中超过了 30 秒的最大执行时间 我该如何解决这个问题? 我已经尝试增加 execution_time,但在时间限制之后出现错误。 但我想了解的主要是为什么代码运行了7-8分钟并显示执行时间超过错误。

【问题讨论】:

max_execution_time 从请求开始到结束计数。调用新函数时它不会重置。如果您需要帮助解决问题,我们需要您的脚本的更多代码用于调试 带有 sendMail() 的代码运行了大约 8 分钟,为什么最大执行时间限制不影响那里? sendMail 函数是否也通过 HTTP 请求执行?还是通过 cli 调用? HTTP 请求 @F***Bettag,使用 PHPMailer 发送邮件 【参考方案1】:

max_execution_time 从请求开始到结束计数。调用新函数时不会重置。

但是,请阅读 https://www.php.net/manual/en/info.configuration.php#ini.max-execution-time 的文档 会告诉你的

最大执行时间不受系统调用、流操作等影响,详情请查看 set_time_limit() 函数。

所以我猜你对邮件服务的调用不计入总执行时间,因此你的脚本可以运行 7-8 分钟,然后最终达到 PHP 运行时限制。

因此,为了解决您在发送电子邮件时脚本遇到超时的问题, 如果您有权访问 php.ini 文件,或者您的 PHP 配置允许 ini_set,您可以增加 max_execution_time,您可以手动增加此特定脚本的限制。

也许您甚至可以在每次成功发送一封电子邮件时使用set_time_limit 来增加最大运行时间。

另一个更复杂但也更健壮的解决方案是实现某种电子邮件队列,然后由 cli 脚本通过 cron 永久处理该队列。 这样,您不必担心超出脚本运行时间。 您可以将有关您需要发送的邮件的所有信息放入文件或数据库表中,您的 cron 脚本可以读取这些作业并执行它们。

【讨论】:

以上是关于PHP max_execution time 是不是在每个函数调用上重置?的主要内容,如果未能解决你的问题,请参考以下文章

php上传大文件失败处理

怎么修改php上传文件文件大小限制

怎么修改php上传文件文件大小限制第一次

PHP函数set_time_limit(0)在空间上不起作用

php 哪个函数可以获取当前时间的毫秒值?在线等

如何检查字符串是不是是有效的 DATE、TIME 或 DATETIME