Laravel源码入门-启动引导过程(八)HandleExceptions
2017-05-18 22:35
501 查看
上文介绍了 LoadConfiguration,载入 config/*.php 配置,在 《Laravel源码入门-启动引导过程(五)$kernel->handle($request)》中第三个要载入的是 HandleExceptions,也就是 Foundation\Http\Kernel::bootstrapers[] 的第三个
\Illuminate\Foundation\Bootstrap\HandleExceptions::class, 如下:
我们再直接贴出 HandleExceptions 类的代码,进行分析,非常直观,如下:
至此所有的错误处理、异常处理、PHP中止处理的准备工作都已配置完成。
\Illuminate\Foundation\Bootstrap\HandleExceptions::class, 如下:
// Illuminate\Foundation\Http\Kernel.php 片段 /** * The bootstrap classes for the application. * 引导类,起引导作用的类 * * @var array */ protected $bootstrappers = [ // 载入服务器环境变量(.env 文件) \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class, // 载入配置信息(config 目录) \Illuminate\Foundation\Bootstrap\LoadConfiguration::class, // 配置如何处理异常 \Illuminate\Foundation\Bootstrap\HandleExceptions::class, // 注册 Facades \Illuminate\Foundation\Bootstrap\RegisterFacades::class, // 注册 Providers \Illuminate\Foundation\Bootstrap\RegisterProviders::class, // 启动 Providers \Illuminate\Foundation\Bootstrap\BootProviders::class, ];
我们再直接贴出 HandleExceptions 类的代码,进行分析,非常直观,如下:
<?php namespace Illuminate\Foundation\Bootstrap; use Exception; use ErrorException; use Illuminate\Contracts\Debug\ExceptionHandler; use Illuminate\Contracts\Foundation\Application; use Symfony\Component\Console\Output\ConsoleOutput; use Symfony\Component\Debug\Exception\FatalErrorException; use Symfony\Component\Debug\Exception\FatalThrowableError; class HandleExceptions { /** * The application instance. * * @var \Illuminate\Contracts\Foundation\Application */ protected $app; /** * Bootstrap the given application. * 引导给定(注入)的 $app。 * * @param \Illuminate\Contracts\Foundation\Application $app * @return void */ public function bootstrap(Application $app) { $this->app = $app; // 报告所有 PHP 错误,和 error_reporting(E_ALL); 一样 // ini_set('error_reporting', E_ALL); // 参考:http://php.net/manual/zh/errorfunc.constants.php error_reporting(-1); // 设置自定义的错误处理方法,数组形式表示 类和类的函数 set_error_handler([$this, 'handleError']); // 设置自定义的异常处理方法 set_exception_handler([$this, 'handleException']); // 注册PHP中止时自定义的处理方法(为什么是 register_ 而不是 set_?) register_shutdown_function([$this, 'handleShutdown']); // 如何应用环境是 .env 文件中 APP_ENV=testing,则关闭错误显示 // 但是,尽管 display_errors 也可以在运行时设置 (使用 ini_set()), // 但是脚本出现致命错误时任何运行时的设置都是无效的。 // 因为在这种情况下预期运行的操作不会被执行 // 参见:http://php.net/manual/zh/errorfunc.configuration.php#ini.display-errors // 这里 environment() 带了参数,据说 php 弱类型,不定义参数也可以传入, // 使用 func_get_arg() 和 func_get_args() 获取,见 $app->environment()源码和php说明。 if (! $app->environment('testing')) { ini_set('display_errors', 'Off'); } } /** * Convert PHP errors to ErrorException instances. * 转换 php 错误 为 ErrorException实例(php内置类) * * handleError() 是按照PHP中set_error_handler(callable $error_handler )中 * $error_handler 严格定义的,参见 set_error_handler 文档,最终由 trigger_error()触发。 * * @param int $level * @param string $message * @param string $file * @param int $line * @param array $context * @return void * * @throws \ErrorException */ public function handleError($level, $message, $file = '', $line = 0, $context = []) { if (error_reporting() & $level) { throw new ErrorException($message, 0, $level, $file, $line); } } /** * Handle an uncaught exception from the application. * 处理程序本身代码未能想到(处理,写代码时想不到的)的异常 * * Note: Most exceptions can be handled via the try / catch block in * the HTTP and Console kernels. But, fatal error exceptions must * be handled differently since they are not normal exceptions. * * 大多数能用 try/catch 捕获到,但是但凡捕获不到的,都作为 Fatal? * * @param \Throwable $e * @return void */ public function handleException($e) { // 记住 instanceof 是运算符,不是函数 if (! $e instanceof Exception) { $e = new FatalThrowableError($e); } // 实例化异常处理对象来报告 $e。 $this->getExceptionHandler()->report($e); if ($this->app->runningInConsole()) { $this->renderForConsole($e); } else { $this->renderHttpResponse($e); } } /** * Render an exception to the console. * 异常渲染到 console * * @param \Exception $e * @return void */ protected function renderForConsole(Exception $e) { $this->getExceptionHandler()->renderForConsole(new ConsoleOutput, $e); } /** * Render an exception as an HTTP response and send it. * 异常渲染到HTTP response,并 send(). * * @param \Exception $e * @return void */ protected function renderHttpResponse(Exception $e) { $this->getExceptionHandler()->render($this->app['request'], $e)->send(); } /** * Handle the PHP shutdown event. * * @return void */ public function handleShutdown() { // $error 由 error_get_last() 返回和定义, // 有固定的 "type"、 "message"、"file" 和 "line" 键值。 if (! is_null($error = error_get_last()) && $this->isFatal($error['type'])) { $this->handleException($this->fatalExceptionFromError($error, 0)); } } /** * Create a new fatal exception instance from an error array. * * @param array $error * @param int|null $traceOffset * @return \Symfony\Component\Debug\Exception\FatalErrorException */ protected function fatalExceptionFromError(array $error, $traceOffset = null) { return new FatalErrorException( $error['message'], $error['type'], 0, $error['file'], $error['line'], $traceOffset ); } /** * Determine if the error type is fatal. * * @param int $type * @return bool */ protected function isFatal($type) { return in_array($type, [E_COMPILE_ERROR, E_CORE_ERROR, E_ERROR, E_PARSE]); } /** * Get an instance of the exception handler. * * @return \Illuminate\Contracts\Debug\ExceptionHandler */ protected function getExceptionHandler() { return $this->app->make(ExceptionHandler::class); } }
至此所有的错误处理、异常处理、PHP中止处理的准备工作都已配置完成。
相关文章推荐
- Laravel源码入门-启动引导过程(四)app/Http/Kernel.php
- Laravel源码入门-启动引导过程(十)RegisterProviders
- Laravel源码入门-启动引导过程(七)LoadConfiguration
- Laravel源码入门-启动引导过程(十二)Pipeline
- Laravel源码入门-启动引导过程(九)RegisterFacades
- Laravel源码入门-启动引导过程(十一)BootProviders
- Laravel源码入门-启动引导过程(六)LoadEnvironmentVariables
- Laravel源码入门-启动引导过程(一)public/index.php
- Laravel源码入门-启动引导过程(三)bootstrap/app.php
- Laravel源码入门-启动引导过程(五)$kernel->handle($request)
- Laravel5.5源码详解 -- 数据库的启动与连接过程
- Laravel源码入门-启动引导过程(二)bootstrap/autoload.php
- U-Boot的启动过程源码分析
- Linux系统启动过程及grub引导故障排错(二)
- Android源码学习之八—系统启动过程
- Linux0.11内核--启动引导过程
- Linux0.11内核--启动引导过程
- pc机,嵌入式系统,启动过程,引导过程,bootloader,grub
- linux grub 引导启动过程详解
- Nginx源码分析-启动初始化过程(二)