首先讲解一下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...