博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP中一个错误的一生
阅读量:6864 次
发布时间:2019-06-26

本文共 4797 字,大约阅读时间需要 15 分钟。

  hot3.png

一,错误的触发

错误的触发方式有:

  • 系统触发错误(比如有未捕获的异常,或参数类型不正确)
  • 用户触发错误trigger_error

特别地,set_exception_handler是用于未捕获异常的自动处理函数,如果注册了回调函数,则正常系统未捕获异常会在调用此函数后视作已处理异常;否则将触发未捕获异常的E_ERROR.

用户级别错误属于E_USER系列,其他的属于系统错误。具体地有:

(来源:)

Value Constant Description Note
1 E_ERROR () Fatal run-time errors. These indicate errors that can not be recovered from, such as a memory allocation problem. Execution of the script is halted.  
2 E_WARNING () Run-time warnings (non-fatal errors). Execution of the script is not halted.  
4 E_PARSE () Compile-time parse errors. Parse errors should only be generated by the parser.  
8 E_NOTICE () Run-time notices. Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script.  
16 E_CORE_ERROR() Fatal errors that occur during PHP's initial startup. This is like an E_ERROR, except it is generated by the core of PHP.  
32 E_CORE_WARNING() Warnings (non-fatal errors) that occur during PHP's initial startup. This is like an E_WARNING, except it is generated by the core of PHP.  
64 E_COMPILE_ERROR() Fatal compile-time errors. This is like an E_ERROR, except it is generated by the Zend Scripting Engine.  
128 E_COMPILE_WARNING() Compile-time warnings (non-fatal errors). This is like an E_WARNING, except it is generated by the Zend Scripting Engine.  
256 E_USER_ERROR() User-generated error message. This is like an E_ERROR, except it is generated in PHP code by using the PHP function .  
512 E_USER_WARNING() User-generated warning message. This is like an E_WARNING, except it is generated in PHP code by using the PHP function .  
1024 E_USER_NOTICE() User-generated notice message. This is like an E_NOTICE, except it is generated in PHP code by using the PHP function .  
2048 E_STRICT () Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your code. Since PHP 5 but not included in E_ALL until PHP 5.4.0
4096 E_RECOVERABLE_ERROR() Catchable fatal error. It indicates that a probably dangerous error occured, but did not leave the Engine in an unstable state. If the error is not caught by a user defined handle (see also ), the application aborts as it was an E_ERROR. Since PHP 5.2.0
8192 E_DEPRECATED() Run-time notices. Enable this to receive warnings about code that will not work in future versions. Since PHP 5.3.0
16384 E_USER_DEPRECATED() User-generated warning message. This is like an E_DEPRECATED, except it is generated in PHP code by using the PHP function . Since PHP 5.3.0
32767 E_ALL () All errors and warnings, as supported, except of level E_STRICT prior to PHP 5.4.0. 32767 in PHP 5.4.x, 30719 in PHP 5.3.x, 6143 in PHP 5.2.x, 2047 previously

二,错误的捕获

一旦错误被触发,它将被捕获并被处理;随之而来的,可能是程序的继续执行,或是程序的终止。一般地说,与这个过程相关的函数和配置有:error_reporting,display_errors,log_errors,set_error_handler。总的来说,错误将会被优先发给用户自定义的错误处理函数,然后交由系统处理。

总的来说,这些错误,有的会只经过自定义函数处理,有的会只经过系统处理,有的是经过自定义函数处理过后,然后再交由系统处理。

预先步骤:

检查是否有错误控制符(@),如果有,将error_reporting的返回值,强制设为0.

1)交由自定义函数处理的情况是(必须同时满足)

a.不属于E_ERROR,E_PARSE,E_CORE_ERRORE_CORE_WARNING,E_COMPILE_ERRORE_COMPILE_WARNING,和大部分的E_STRICT的错误类型(我们姑且称之为”严重错误“和”普通错误“)

b.注册了一个set_error_handler处理函数

c.set_error_handler的第二个参数,与该错误类型的整数位相与,结果不为0

其他情况,转入步骤三

2)调用set_error_handler函数对错误进行处理,满足以下情况转入步骤三,其他情况跳出错误处理过程:

a.set_error_handler处理结束之后,返回的结果为false值

3)系统处理的过程是:

a.查看error_reporting的值,与错误类型的整数进行位相与,如果结果为0,转入步骤四

b.如果display_errors为true,将错误输出到标准输出流

c.如果log_errors为true,将结果记录进日志(由error_log配置决定日志位置,如果没有)

4)最后一个步骤,决定程序的走向

a.如果是非致命性错误,程序将继续执行

b.如果是致命性错误,则

(1)如果使用register_shutdown_function注册了结束函数,调用结束函数,否则直接转入下面步骤

(2)符合以下情况则将http状态改为500

    (a)display_errors为false

    (b)在错误发生前,尚未发送header数据

    (c)目前的http状态为200

(3)结束程序

三,设计健壮的错误处理方法

这个错误处理方法,要达成以下目标:

1)非常健壮,能够在触发致命性错误的时候,依旧可以处理,而不是直接退出

2)非常安全,不会向终端用户泄露关于程序处理过程的信息

3)非常友好,终端用户看到尽可能少的信息而开发者能看到尽可能多的信息

我的设计思路如下:

0)总体思路:首先,我们必须知道,一致的意外情况处理方法非常重要,而php既有error又有exception的方式是历史原因。所以,第一,不要使用trigger_error来触发自定义错误,而应当抛出异常;第三,系统的普通错误信息由于是历史原因,无法改写,应当调用set_error_handler包装为异常予以处理;第三,系统的严重错误可以调用register_shutdown_function包装成异常予以处理。这样的话,所有的错误和异常都被当作异常,通过一致的方式,予以处理。

对于错误的信息,应当调用debug_backtrace进行详细分析。设计的最终步骤如下:

1)我们观察到系统的错误处理过程,是display_errors和log_errors,这两种我们都可以在自定义的错误处理函数中予以解决,因此,第一步,关闭系统错误处理ini_set('display_errors',false),ini_set('log_errors',false)。为什么不直接error_reporting(0)呢?因为我们可以利用error_reporting来自定义忽略一些错误,更重要的是为了@操作符也能够发挥应有的效果。

2)调用set_exception_handler()定义一个异常的处理函数ExceptionHandler(),这个函数主要用于处理未经处理的异常,尤其重要的是,它将用来处理我们的错误异常ErrorException(包括致命性错误)。这是我们的核心处理部分。

3)通过set_error_handler,普通错误全部捕获,调用error_reporting查看是否应该忽略该错误,如果不应当忽略,则在error_handler内部将错误包装为ErrorException,调用ExceptionHandler($error)。

4)注册一个register_shutdown_function,处理致命性错误发生的行为,调用ExceptionHandler。

通过以上步骤,可以建立起一个安全高效和稳健的错误处理流程。此外,还可以通过配置,对生产和开发环境使用有所区别的方式。

最后,推荐使用facebook出品的xhprof来监控系统的性能。

转载于:https://my.oschina.net/sefier/blog/84832

你可能感兴趣的文章
OBS插件学习入门:一个非常简单的、调节音量的filter
查看>>
[Lua]50行代码的解释器,用来演示lambda calculus
查看>>
socketserver模块解析
查看>>
使用winrar自解压功能制作安装包
查看>>
web crawling(plus4) pretend to be A web
查看>>
python (ploit3)hexun
查看>>
ASP.NET 学习笔记_01 广告控件的使用
查看>>
在vue-cli项目中使用echarts
查看>>
原生JS实现$.ajax
查看>>
Cocoa 框架 For iOS(二)对象的分配初始化、内省、单例
查看>>
参数和指针
查看>>
点滴积累【C#】---初始页面自动给站点名称赋值
查看>>
Java中程序初始化的顺序
查看>>
C++程序设计(第二版)谭浩强----程序题课后习题答案第二章
查看>>
GMap.net 离线地图问题
查看>>
C# 利用Jmail接收邮件
查看>>
安全退出调用多个Activity的Application
查看>>
让织梦CMS的后台编辑器支持优酷视频
查看>>
列表导航栏实例(01)
查看>>
压缩aspx页面,移除aspx多余的空格 供学习参考
查看>>