根据文件:
max_execution_time only affect the execution time of the script itself. Any time spent on activity that happens outside the execution of the script such as system calls using system(), stream operations, database queries, etc. is not included when determining the maximum time that the script has been running. This is not true on Windows where the measured time is real.
这是通过testing确认的:
不会超时
<?php set_time_limit(5); $sql = mysqli_connect('localhost','root','root','mysql'); $query = "SELECT SLEEP(10) FROM mysql.user;"; $sql->query($query) or die($query.'<br />'.$sql->error); echo "You got the page";
会超时
<?php set_time_limit(5); while (true) { // do nothing } echo "You got the page";
我们的问题是,我们真的希望在给定的时间量之后,PHP会暂停,不pipe它在做什么(因为如果我们知道我们没有以可接受的数量交付页面,我们不想让资源忙碌的时间,如10秒)。 我们知道我们可以使用像SQL查询的MySQL wait_timeout这样的设置,但页面超时将取决于执行的查询数量。
有些人试图想出解决办法 ,似乎不可行。
问:是否有一种简单的方法可以在Linux上获得真正的PHP max_execution_time
,或者我们是否更好地在其他地方(如Apache
级别)超时?
这是一个相当棘手的建议,但它肯定会做你想做的,如果你愿意修改和重新编译PHP。
在函数zend_set_timeout
处,查看https://github.com/php/php-src/blob/master/Zend/zend_execute_API.c处的PHP源代码(该文件是Zend/zend_execute_API.c
)。 这是实现时间限制的功能。 以下是它在不同平台上的工作原理:
在Windows上,创建一个新的线程,在其上启动一个定时器,当它完成时,设置一个名为timed_out
的全局变量为1,PHP执行核心检查这个变量的每条指令,然后退出(非常简化)
在Cygwin上,使用itimer与ITIMER_REAL,它测量实时 ,包括任何睡眠,等待,无论如何,然后提出一个信号 ,将中断任何处理,并停止处理
在其他unix系统上,使用itimer与ITIMER_PROF,它只测量当前进程花费的CPU时间(但在用户模式和内核模式下)。 这意味着等待其他进程(如MySQL)不计入此。
现在你想要做的就是把你的Linux上的itimer从ITIMER_PROF更改为ITIMER_REAL,这当然需要手动,重新编译,安装等。这两者之间的另一个区别是当定时器运行时它们也使用不同的信号出。 所以我的建议是改变ifdef:
# ifdef __CYGWIN__
成
# if 1
以便您将ITIMER_REAL和PHP等待的信号都设置为SIGALRM。
无论如何,这个想法是没有经过测试的(我用它来做一些非常特殊的系统,ITIMER_PROF被破坏了,它似乎可以正常工作),不受支持等等。使用它需要您自担风险。 它可能与PHP本身工作,但它可能会打破其他模块,在PHP 和 Apache,如果他们出于任何原因,使用SIGALRM信号或其他计时器。
这是一个古老而又回答的问题。 但为了帮助别人,我想指出request_terminate_timeout
php-fpm选项。 如果您使用的是PHP-FPM,那很可能是您需要的。
如果设置,这个选项允许你告诉PHP-FPM在N秒之后终止一个请求,而不管PHP做什么。
有关详细信息,请参阅http://php.net/manual/en/install.fpm.configuration.php#request-terminate-timeout 。
从httpd.conf:
超时:接收和发送超时之前的秒数
超时300