## 从public目录下的index.php入口文件开始
显示require把base.php文件加载进来。base.php主要干了以下事情
1. 载入了系统的自动加载类(think\Loader.php)。
2. 注册了自动加载类。
3. 注册错误和异常处理机制
4. 注册类库别名
### 注册错误和异常处理机制
类的自动加载在第一章分析过。接下来我们分析一下错误和异常处理。调用的是Error类的register方法。
```
Error::register();
```
由于前面已经注册了类的自动加载,所以这里可以接着加载到think\Error的类。并调用静态方法register
```
public static function register() {
error_reporting(E_ALL); // 设置应该报告何种php错误
set_error_handler([__CLASS__, 'appError']); // 设置用户自定义的错误处理函数
set_exception_handler([__CLASS__, 'appException']); // 设置用户自定义的异常处理函数
register_shutdown_function([__CLASS__, 'appShutdown']); //它会在脚本执行完成或者exit后被调用
}
```
> error_reporting(E_ALL); 报告所有的php错误。(即所有的错误都打印出来)
* set_error_handler设置了appError函数为自定义错误处理函数。看一下这个函数。
将错误号码和设置的报告错误级别进行位运算,若匹配,则直接抛出错误。若不匹配,则走向框架内置的ExceptionHandler中的report方法。report方法主要是记录日志信息。
```
public static function appError($errno, $errstr, $errfile = '', $errline = 0){
$exception = newErrorException($errno, $errstr, $errfile, $errline);
if (error_reporting() & $errno) {
// 将错误信息托管至 think\\exception\\ErrorException
throw $exception;
}
self::getExceptionHandler()->report($exception);
}
```
* set_exception_handler设置了appException函数为自定义的异常处理函数。看一下这个函数.
先调用report方法记录日志。在判断若是命令行运行,则命令行打印异常信息,若是网页,则调用
ExceptionHandler的render方法将处理异常,最终将调用response的send方法把异常处理后的信息展示在浏览器端。
```
public static function appException($e) {
// 自定义异常必须继承\Exception类
if (!$e instanceof \Exception) {
$e = newThrowableError($e);
}
self::getExceptionHandler()->report($e);
if (PHP\_SAPI == 'cli') {
self::getExceptionHandler()->renderForConsole(newConsoleOutput, $e);
} else {
self::getExceptionHandler()->render($e)->send();
}
}
```
上面的self::getExceptionHandler,如果不设置的话,默认的是think\exception\Handle类。我们可以自定义一个类。但必须是需要继承think\exception\Handle。并重写父类的render方法。从而实现自定义异常的处理。(我们可以自定义一个类,然后再配置文件中配置exception\_handle属性即可)
> 自定义异常处理的主要作用是根据不同的异常类型发送不同的状态码和响应输出格式。需要注意的是,如果自定义异常处理类没有再次调用系统`render`方法的话,配置`http_exception_template`就不再生效
* register_shutdown_function注册了appShutdown函数为程序结束时调用的函数。该函数先是判断是否是致命的错误导致程序结束,如果是则调用自定义错误处理函数。最后将信息写入日志。
```
public static function appShutdown(){
if (!is_null($error = error_get_last()) && self::isFatal($error['type'])) {
// 将错误信息托管至think\ErrorException
$exception = new ErrorException($error['type'], $error['message'], $error['file'], $error['line']);
self::appException($exception);
}
// 写入日志
Container::get('log')->save();
}
```
> error_get_last 函数返回最后一次发生错误的信息