| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 | <?php// +----------------------------------------------------------------------// | ThinkPHP [ WE CAN DO IT JUST THINK ]// +----------------------------------------------------------------------// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.// +----------------------------------------------------------------------// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )// +----------------------------------------------------------------------// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>// +----------------------------------------------------------------------namespace think;use think\console\Output as ConsoleOutput;use think\exception\ErrorException;use think\exception\Handle;use think\exception\ThrowableError;class Error{    /**     * 配置参数     * @var array     */    protected static $exceptionHandler;    /**     * 注册异常处理     * @access public     * @return void     */    public static function register()    {        error_reporting(E_ALL);        set_error_handler([__CLASS__, 'appError']);        set_exception_handler([__CLASS__, 'appException']);        register_shutdown_function([__CLASS__, 'appShutdown']);    }    /**     * Exception Handler     * @access public     * @param  \Exception|\Throwable $e     */    public static function appException($e)    {        if (!$e instanceof \Exception) {            $e = new ThrowableError($e);        }        self::getExceptionHandler()->report($e);        if (PHP_SAPI == 'cli') {            self::getExceptionHandler()->renderForConsole(new ConsoleOutput, $e);        } else {            self::getExceptionHandler()->render($e)->send();        }    }    /**     * Error Handler     * @access public     * @param  integer $errno   错误编号     * @param  integer $errstr  详细错误信息     * @param  string  $errfile 出错的文件     * @param  integer $errline 出错行号     * @throws ErrorException     */    public static function appError($errno, $errstr, $errfile = '', $errline = 0)    {        $exception = new ErrorException($errno, $errstr, $errfile, $errline);        if (error_reporting() & $errno) {            // 将错误信息托管至 think\exception\ErrorException            throw $exception;        }        self::getExceptionHandler()->report($exception);    }    /**     * Shutdown Handler     * @access public     */    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();    }    /**     * 确定错误类型是否致命     *     * @access protected     * @param  int $type     * @return bool     */    protected static function isFatal($type)    {        return in_array($type, [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE]);    }    /**     * 设置异常处理类     *     * @access public     * @param  mixed $handle     * @return void     */    public static function setExceptionHandler($handle)    {        self::$exceptionHandler = $handle;    }    /**     * Get an instance of the exception handler.     *     * @access public     * @return Handle     */    public static function getExceptionHandler()    {        static $handle;        if (!$handle) {            // 异常处理handle            $class = self::$exceptionHandler;            if ($class && is_string($class) && class_exists($class) && is_subclass_of($class, "\\think\\exception\\Handle")) {                $handle = new $class;            } else {                $handle = new Handle;                if ($class instanceof \Closure) {                    $handle->setRender($class);                }            }        }        return $handle;    }}
 |