CodeIgniter 源码分析-> error_hander

_error_handler 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
if ( ! function_exists('_error_handler'))
{
/**
* Error Handler
*
* This is the custom error handler that is declared at the (relative)
* top of CodeIgniter.php. The main reason we use this is to permit
* PHP errors to be logged in our own log files since the user may
* not have access to server logs. Since this function effectively
* intercepts PHP errors, however, we also need to display errors
* based on the current error_reporting level.
* We do that with the use of a PHP error template.
*
* @param int $severity
* @param string $message
* @param string $filepath
* @param int $line
* @return void
*/
function _error_handler($severity, $message, $filepath, $line)
{
// @todo 已解决 - 如何进行的错误控制
// $severity 是此 5 个错误等级中的一个时, 那么 is_error 为真
// E_ERROR: 1(1), E_PARSE: 4(100), E_COMPILE_ERROR: 64(1000000), E_CORE_ERROR: 16(10000), E_USER_ERROR: 256(100000000)
$is_error = (((E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity);

// When an error occurred, set the status header to '500 Internal Server Error'
// to indicate to the client something went wrong.
// This can't be done within the $_error->show_php_error method because
// it is only called when the display_errors flag is set (which isn't usually
// the case in a production environment) or when errors are ignored because
// they are above the error_reporting threshold.
if ($is_error)
{
set_status_header(500);
}

// Should we ignore the error? We'll get the current error_reporting
// level and add its bits with the severity bits to find out.
if (($severity & error_reporting()) !== $severity)
{
return;
}

$_error =& load_class('Exceptions', 'core');
$_error->log_exception($severity, $message, $filepath, $line);

// Should we display the error?
if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors')))
{
$_error->show_php_error($severity, $message, $filepath, $line);
}

// If the error is fatal, the execution of the script should be stopped because
// errors can't be recovered from. Halting the script conforms with PHP's
// default error handling. See http://www.php.net/manual/en/errorfunc.constants.php
if ($is_error)
{
exit(1); // EXIT_ERROR
}
}
}
1
2
3
// $severity 是此 5 个错误等级中的一个时, 那么 is_error 为真
// E_ERROR: 1(1), E_PARSE: 4(100), E_COMPILE_ERROR: 64(1000000), E_CORE_ERROR: 16(10000), E_USER_ERROR: 256(100000000)
$is_error = (((E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity);

其中 E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR 得到值为 341(101010101)

101010101 & $severity 对传进来的 $severity 进行位与运算.

如果结果和自身相等(即 $severity 等于 E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR 中的某一个) 那么 $is_error 为真

接下来跟系统的错误等级比较, 判断是否要显示错误

如果需要显示, 那么就会记录日志, 显示错误, 停止继续执行.