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 是不是在每个函数调用上重置?的主要内容,如果未能解决你的问题,请参考以下文章