为了能让自定义的错误及异常处理机制能够捕获到致命错误,在thinkphp的fatalError()方法了添加了 trigger_error($e['message']);
// 重新设置错误及异常处理机制
set_error_handler(array('\Think\ErrorLog','phplog'));
set_exception_handler(array('\Think\ErrorLog','phplog'));
// 致命错误捕获
static public function fatalError() {
Log::save();
if ($e = error_get_last()) {
switch($e['type']){
case E_ERROR:
case E_PARSE:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
ob_end_clean();
// 抛出用户级别错误,让自定义的错误机制(phplog)能够捕获
trigger_error($e['message']); //自己添加的
self::halt($e);
break;
}
}
}
下面是自己的错误机制
public static function phplog($errno, $errstr = null, $errfile = null, $errline= null) {
if($errstr === null) { //异常
$backtrace = array(
'logType' => 'exception',
'environment' => array(
'code' => $errno->getCode(), //异常代码
'message' => $errno->getMessage(), //异常消息
'file' => $errno->getFile(), //异常文件
'line' => $errno->getLine(), //异常行
'debugBacktrace' => $errno->getTrace() //异常追踪
)
);
} else if( error_reporting() ) { //常规错误
$backtrace = array(
'logType' =>'error',
'environment' => array(
'code' => $errno,
'message' => $errstr,
'file' => $errfile,
'line' => $errline,
'debugBacktrace' => debug_backtrace() //错误回溯
)
);
} else { //"@"错误
return ;
}
$index = iconv('UTF-8', 'UTF-8//IGNORE', $index = &$backtrace['environment']['message']); //移除无效字符
self::formatLog($backtrace); //格式化日志
$errorLevel = array( //输出日志信息
0 => 'Exception', //异常
1 => 'E_ERROR', //致命的运行时错误。错误无法恢复。脚本的执行被中断。
2 => 'E_WARNING', //非致命的运行时错误。脚本的执行不会中断。
4 => 'E_PARSE', //编译时语法解析错误。解析错误只应该由解析器生成。
8 => 'E_NOTICE', //运行时提示。可能是错误,也可能在正常运行脚本时发生。
16 => 'E_CORE_ERROR', //由 PHP 内部生成的错误。
32 => 'E_CORE_WARNING', //由 PHP 内部生成的警告。
64 => 'E_COMPILE_ERROR', //由 Zend 脚本引擎内部生成的错误。
128 => 'E_COMPILE_WARNING', //由 Zend 脚本引擎内部生成的警告。
256 => 'E_USER_ERROR', //由于调用 trigger_error() 函数生成的运行时错误。
512 => 'E_USER_WARNING', //由于调用 trigger_error() 函数生成的运行时警告。
1024 => 'E_USER_NOTICE', //由于调用 trigger_error() 函数生成的运行时提示。
2048 => 'E_STRICT', //运行时提示。对增强代码的互用性和兼容性有益。
4096 => 'E_RECOVERABLE_ERROR', //可捕获的致命错误。
8192 => 'E_DEPRECATED', //运行时通知。启用后将会对在未来版本中可能无法正常工作的代码给出警告。
16384 => 'E_USER_DEPRECATED', //用户产少的警告信息。
30719 => 'E_ALL', //所有的错误和警告,除了 E_STRICT。
);
$temp = htmlentities($index, ENT_QUOTES, 'UTF-8');
self::writeLog($backtrace, 'php', "<font style='display:block; color:#F00; font-weight:bold;'>{$errorLevel[$backtrace['environment']['code']]} : \"<pre style='display: inline;'>{$temp}</pre>\" in {$backtrace['environment']['file']} on line {$backtrace['environment']['line']}. Timestamp : {$_SERVER['REQUEST_TIME']}</font>");
}
protected static function writelog(&$logData, $logType, $printStr) {
self::$lastError['error'] = &$logData;
if( APP_DEBUG ) { //debug模式
echo $printStr; //打印日志
}
$logPath = RUNTIME_PATH . 'Errorlog' . date('/Y/m/d', $_SERVER['REQUEST_TIME']) . $logType;
echo realpath(RUNTIME_PATH); // 结果1.D:\wamp\www\XMQZ\Runtime 结果2.D:\wamp\Apache24\Runtime
is_dir($temp = dirname($logPath)) || mkdir($temp, 0777, true);
@file_put_contents(
$logPath,
strtr(serialize($logData), array("\r\n" => ' ' . ($temp = chr(0)), "\r" => $temp, "\n" => $temp)) . "\n",
FILE_APPEND | LOCK_EX
);
}