首先在 Think\Think::start() 静态方法中,使用 register_shutdown_function 函数注册致命错误处理方法。

register_shutdown_function('Think\Think::fatalError');

Think\Think::fatalError 方法中,首先记录错误日志,这个暂且不说。接着使用 error_get_last 函数获取错误信息,不过TP只匹配E_ERROR、E_PARSE、E_CORE_ERROR、E_COMPILE_ERROR、E_USER_ERROR 这五种错误类型,然后使用 ob_end_clean 函数清空并关闭输出缓冲区(这样做的目的是,不显示PHP自身的错误信息提示,而是采用自定义的错误提示),最后调用自定义错误提示方法。

// 致命错误捕获
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();self::halt($e);break;}}
}

self::halt($e) 方法细节:

// 错误输出
static public function halt($error)
{$e = array();if (APP_DEBUG || IS_CLI) {//调试模式下输出错误信息if (!is_array($error)) {// 如果错误信息格式不是数组,使用回溯跟踪函数debug_backtrace,可以定位到错误文件及错误行号。$trace          = debug_backtrace();$e['message']   = $error;$e['file']      = $trace[0]['file'];$e['line']      = $trace[0]['line'];// 开启并打印输出缓冲区的内容ob_start();debug_print_backtrace();$e['trace']     = ob_get_clean();} else {$e              = $error;}if(IS_CLI){// 如果开启了命令行模式,直接输出错误信息。exit(iconv('UTF-8','gbk',$e['message']).PHP_EOL.'FILE: '.$e['file'].'('.$e['line'].')'.PHP_EOL.$e['trace']);}} else {//否则定向到错误页面$error_page         = C('ERROR_PAGE');if (!empty($error_page)) {// 获取错误文件的URL路径,重定向至错误的文件,一般不会执行这段代码。redirect($error_page);} else {// 在线上部署时,出于安全考虑,不应显示过多的敏感信息,// 比如:错误文件及路径,错误行号,错误原因。// C('SHOW_ERROR_MSG')为false时,显示tp预定义好的错误提示:C('ERROR_MESSAGE') 页面错误!请稍后再试~。$message        = is_array($error) ? $error['message'] : $error;$e['message']   = C('SHOW_ERROR_MSG')? $message : C('ERROR_MESSAGE');}}// 最后一步就是加载错误模板,想用户展示错误信息// 路径:项目根\ThinkPHP\Tpl\think_exception.tpl// 至于模板是什么样子,自己可以随意写。// 包含异常页面模板$exceptionFile =  C('TMPL_EXCEPTION_FILE',null,THINK_PATH.'Tpl/think_exception.tpl');include $exceptionFile;exit;
}

1、ThinkPHP源码学习-致命错误捕获及自定义错误输出相关推荐

  1. ThinkPHP源码学习之一

    接触TP的时间已久,中间因为工作原因没能一直在TP上有所深入学习,今日,在原公司离职之日.重新踏上TP的学习.这次想深入的研究一遍源码.仅此作为自己在TP路上的见证. thinkPHP的引导文件run ...

  2. ThinkPHP源码学习之I方法

    PHP新人一个,最近在做一个项目,用的是ThinkPHP,想往深处学习,特意学习ThinkPHP的源码并作笔记,以记录这些容易忘记的东西,废话不多说,开始. 官网说明: I方法是ThinkPHP众多单 ...

  3. ThinkPHP源码学习 data_to_xml函数 数据转成xml格式

    /**  * 数据XML编码  * @param mixed  $data 数据  * @param string $item 数字索引时的节点名称  * @param string $id   数字 ...

  4. Mybatis源码学习(三)SqlSession详解

    前言 上一章节我们学习了SqlSessionFactory的源码,SqlSessionFactory中的方法都是围绕着SqlSession来的.,那么SqlSession又是什么东东呢?这一章节我们就 ...

  5. DotText源码学习——ASP.NET的工作机制

    --本文是<项目驱动学习--DotText源码学习>系列的第一篇文章,在这之后会持续发表相关的文章. 概论 在阅读DotText源码之前,让我们首先了解一下ASP.NET的工作机制,可以使 ...

  6. ThinkPHP源码解析之控制器

    本文会对控制器的执行顺序还有实现过程.源码解析给出解析, ThinkPHP源码解析之控制器 前言 一.实例化控制器 二.关于ArrayAccess和直接执行魔术访问返回实例的区别 三.执行控制器中的方 ...

  7. koa 基础入门与源码学习

    Koa 学习笔记 本期内容主要为 koa 基础与源码学习,后续会开一期 koa 项目实战.本文基础部分目录结构按照阮一峰老师的 koa 教程(有作修动).望本文能对您有所帮助!☀️ 前置基础 node ...

  8. Shiro源码学习之二

    接上一篇 Shiro源码学习之一 3.subject.login 进入login public void login(AuthenticationToken token) throws Authent ...

  9. Shiro源码学习之一

    一.最基本的使用 1.Maven依赖 <dependency><groupId>org.apache.shiro</groupId><artifactId&g ...

最新文章

  1. 谷歌提出纯 MLP 构成的视觉架构,无需卷积、注意力 !
  2. debian apt-get 更新源文件格式说明
  3. js rsa解密中文乱码_建议收藏 | 最全的 JS 逆向入门教程合集
  4. 最近读的那些性能测试书
  5. python爬虫lxml xpath测试
  6. encrypt函数c语言,Crypt加密函数简介(C语言)
  7. 运行时异常与一般异常有何异同?
  8. 7-4 统计Java程序中关键词的出现次数 (25 分)
  9. 韩信点兵 详解(C++)
  10. 光储充一体化充电站,新能源汽车充电桩节能解决方案
  11. pentium500微型计算机,pentium g6950_pentium500微型计算机_pentium ivcpu时钟频率(2)
  12. banner设圆角_com.youth.banner.Banner 使用glide加载圆角图片无效
  13. winform窗口的切换
  14. c语言转fpga原理,要想玩转FPGA,就必须理解FPGA内部的工作原理-可编程逻辑-与非网...
  15. 线形回归和梯度下降的Python实例。
  16. HEVC(H.265) 基础知识
  17. webdriver高级应用- 浏览器中新开标签页(Tab)
  18. 条码标签设计软件Nicelabel使用方法
  19. epic服务器状态,对 Epic Games 启动程序问题进行故障排除
  20. 渗透之信息收集准备工作(利用辅助工具与网站查询)

热门文章

  1. python技术简介_Python简介
  2. SQL Server数据库简介
  3. 优秀程序员共有的7种优秀编程习惯
  4. oracle中实例与数据库的概念解释
  5. 【20保研】清华-伯克利深圳学院2019年暑期夏令营招募通知
  6. 上期所API头文件一、ThostFtdcUserApiStruct.h---API结构体的定义及工作流程(源代码6.3.19版)
  7. C#Lesson09 面向对象
  8. 班主任对学生的成绩分析
  9. 2018年双11预售怎么玩 如何跟上双11活动节奏
  10. “投我以木桃,报之以琼瑶”的真正含义