php 5.3.10 error日志时间bug

首先讲解一下php5.3.10 和 php.5.4.28 中 打印php_error_docref 函数执行流程

(方便大家自己快速阅读定位源码,此函数 会打印日志到php.ini 配置文件中error_log指令配置的日志一条记录:)

 例如 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "redis RINIT..."); 

 打印结果:[23-Oct-2015 10:05:32 Asia/Shanghai] PHP Notice:  Unknown: redis RINIT... in Unknown on line 0


  php_module_startup 函数会设置php默认的错误处理机制(zuf.error_function = php_error_cb;)

函数执行流程:

php_error_docref ->php_error_docref0->php_verror->php_error=zend_error->zend_error_cb=php_error_cb->php_log_err

以下则是形成php errorr日志时间部分的核心代码(这里删除不不必要部分,注释是本人自己添加):

php_log_err函数位于 main/main.c中

php_format_date函数位于 ext/date/php_date.c 中

php5.4.28

time(&error_time);

char * error_time_str;

if (!php_during_module_startup()) {//此处表示 是否在启动过程中
error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 1 TSRMLS_CC);
} else {
error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 0 TSRMLS_CC);//程序运行期间 大多数走此流程

}

php5.3.10

char *error_time_str;
time(&error_time);
error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 0 TSRMLS_CC);
len = spprintf(&tmp, 0, "[%s] %s%s", error_time_str, log_message, PHP_EOL);


php_format_date函数原型(5.3.10和5.4.28源码一样):

PHPAPI char *php_format_date(char *format, int format_len, time_t ts, int localtime TSRMLS_DC) /* {{{ */
{
timelib_time   *t;
timelib_tzinfo *tzi;
char *string;


t = timelib_time_ctor();


if (localtime) {  //php5.4.28 在启动后(php_during_module_startup()返回1)始终显示本地时间
tzi = get_timezone_info(TSRMLS_C); //读取php.ini 中 date_timezone配置 例如 Asia/Shanghai
t->tz_info = tzi;
t->zone_type = TIMELIB_ZONETYPE_ID;
timelib_unixtime2local(t, ts); 
} else {
tzi = NULL;
timelib_unixtime2gmt(t, ts);  //php5.3.10 由于localtime 参数为0 所以始终显示 UTC时间(即gmt)
}


string = date_format(format, format_len, t, localtime);

timelib_time_dtor(t);
return string;
}


相信大家看了上面的 后。。应该知道php5.3 为什么设置了 php.ini 中data_timezone配置后。。error日志中的 时间前缀 始终是UTC格式了。。。。这是php5.3.10的一个bug...


你可能感兴趣的:(php 5.3.10 error日志时间bug)