首页 > 开发 > Php > 正文

php脚本运行时的超时机制详解

2020-02-21 20:43:29
字体:
来源:转载
供稿:网友

在做php开发的时候,经常会设置max_input_time、max_execution_time,用来控制脚本的超时时间。但却从来没有思考过背后的原理。

趁着这两天有空,研究一下这个问题。

超时配置

php的ini配置如何起作用,这是一个老生常谈的话题了。

首先,我们在php.ini里进行配置。当php启动的时候(php_module_startup阶段),会尝试读取ini文件并解析。解析过程简单来说,是分析ini文件,提取出其中合法的键值对,并保存到configuration_hash表。

OK,然后php会进一步调用zend_startup_extensions来启动各个模块(包含php Core模块,以及所有需要加载的扩展)。各个模块的启动函数中,会完成REGISTER_INI_ENTRIES动作。REGISTER_INI_ENTRIES负责将模块对应的一些配置从configuration_hash表取出,然后调用处理函数,最终将处理完的值存入模块的globals变量。

max_input_time、max_execution_time这两个配置属于php Core模块。对于php Core来说,REGISTER_INI_ENTRIES依然发生在php_module_startup中。同样属于php Core模块的配置还有expose_php、display_errors、memory_limit等等...

示意图如下:

---->php_module_startup----------->php_request_startup---->    |    |    |-->REGISTER_INI_ENTRIES    |    |    |-->zend_startup_extensions    |     |    |     |-->zm_startup_date    |     |     |-->REGISTER_INI_ENTRIES    |     |    |     |-->zm_startup_json    |     |     |-->REGISTER_INI_ENTRIES    |    |    |-->do otherthings

上面说到对于不同的配置,REGISTER_INI_ENTRIES会调用不同的函数来处理。我们直接来看max_execution_time对应的函数:

static PHP_INI_MH(OnUpdateTimeout){  // php启动阶段走这里  if (stage == PHP_INI_STAGE_STARTUP) {    // 将超时设置保存到EG(timeout_seconds)中    EG(timeout_seconds) = atoi(new_value);    return SUCCESS;  }   // php执行过程中的ini set则走这里  zend_unset_timeout(TSRMLS_C);  EG(timeout_seconds) = atoi(new_value);  zend_set_timeout(EG(timeout_seconds), 0);  return SUCCESS;}

暂时只看上半截,因为我们目前只需关注php的启动阶段,该函数行为很简单,将max_execution_time存入了EG(timeout_seconds)。

至于max_input_time,并没有特殊的处理函数,默认是会将max_input_time存入存入PG(max_input_time)。

因此,当REGISTER_INI_ENTRIES完成,发生的是:

max_execution_time ----> 存入EG(timeout_seconds)

max_input_time       ----> 存入PG(max_input_time)

请求超时控制

现在我们搞清楚php的启动阶段发生了什么,继续来看php在实际处理请求的时候,如何管理超时。

在php_request_startup函数中有如下代码:

if (PG(max_input_time) == -1) {  zend_set_timeout(EG(timeout_seconds), 1);} else {  zend_set_timeout(PG(max_input_time), 1);}            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表