百科狗-知识改变命运!
--

set_exception_handler() - php 错误处理日志函数

是丫丫呀1年前 (2023-11-21)阅读数 20#技术干货
文章标签异常

set_exception_handler()

(PHP 5, PHP 7)

设置用户自定义的异常处理函数

说明

set_exception_handler(callable $exception_handler):callable

设置默认的异常处理程序,用于没有用 try/catch 块来捕获的异常。在$exception_handler调用后异常会中止。

参数

$exception_handler

当一个未捕获的异常发生时所调用函数的名称。该处理函数需要接受一个参数,该参数是一个抛出的异常对象。 PHP 7 以前的异常处理程序签名:

set_exception_handler() - php 错误处理日志函数

handler(Exception$ex): void

自 PHP 7 以来,大多数错误抛出Error异常,也能被捕获。Error和Exception都实现了Throwable接口。 PHP 7 起,处理程序的签名:

handler(Throwable$ex): void

也可以传递NULL值用于重置异常处理函数为默认值。

Caution

注意,如果在用户回调里将$ex参数的类型明确约束为Exception, PHP 7 中由于异常类型的变化,将会产生问题。

返回值

返回之前定义的异常处理程序的名称,或者在错误时返回NULL。如果之前没有定义错误处理程序,也会返回NULL

更新日志

版本说明
7.0.0传入$exception_handler的参数从Exception改为Throwable
5.5.0之前版本里,如果传入NULL,函数会返回TRUE。自 PHP 5.5.0 后,会返回上一次的异常处理器。

范例

Example #1set_exception_handler()范例

参见

  • restore_exception_handler() 恢复之前定义过的异常处理函数。
  • restore_error_handler() 还原之前的错误处理函数
  • error_reporting() 设置应该报告何种 PHP 错误
  • callback类型的信息
  • PHP 5 异常
Things you should be aware of:
An exception handler handles exceptions that were not caught before. It is the nature of an exception that it discontinues execution of your program - since it declares an exceptional situation in which the program cannot continue (except you catch it).
Since it has not been catched your code signals it is not being aware of the situation and cant go on.
This implies: returning to the script is simply impossible when the exception handler has already been called, since an uncaught exception is not a notice. use your own debug- or notice-log-system for things like that.
Furthermore: While is is still possible to call functions from your script, since the exception handler has already been called exceptions bubbling from that piece of code won't trigger the exception handler again. php will die without leaving any information apart form "uncaught exception with unknown stack frame". So if you call functions from your script, make sure that you catch any exceptions that possibly occur via try..catch inside the exception handler.
For those of you who misinterpreted the essential meaning of the exception handler: it's only use is to handle the abortion of your script gracefully, e.g. in a project like facebook or wikipedia: render a nice error page, eventually hiding information which shall not leak into the public (instead you may want to write to your log or mail the sys-admin or stuff like that).
In other words: Redirecting all php-errors form an error-handler using exceptions - including notices - is a very dumb idea, if you do not intend having your script aborted everytime you didn't set a variable (for example).
my 2 cents.
If you want a class instance to handle the exception, this is how you do it :

See the first post (Sean's) for a static example. As Sean points out, the exception_handler function must be declared public.
A behaviour not documented or discussed enough, yet pretty common is that is that if an exception is thrown from the global exception handler then a fatal error occurs (Exception thrown without a stack frame). That is, if you define your own global exception handler by calling set_exception_handler() and you throw an exception from inside it then this fatal error occurs. It is only natural though, as the callback defined by set_exception_handler() is only called on uncaught (unhandled) exceptions so if you throw one from there then you get this fatal error as there is no exception handler left (you override the php internal one by calling set_exception_handler()), hence no stack frame for it.
Example:

Will cause a Fatal error: Exception thrown without a stack frame
If you skip/comment the set_exception_handler("...") line then the internal PHP global handler will catch the exception and output the exception message and trace (as string) to the browser, allowing you to at least see the exception message.
While it is a very good idea to always define your own global exception handler by using the set_exception_handler() function, you should pay attention and never throw an exception from it (or if you do then catch it).
Finally, every serious coder should use an IDE with debugging capabilities. Tracking down an error like this becomes a trivial matter by using simple debugging "Step into" commands (I for one recommend Zend IDE v5.2 at the moment of this writing). I have seen numerous messages on the internet with people wondering why this message pops up.
Cheers
p.s. Other causes for this error which are somehow unrelated to this is when you throw an exception from a destructor (the reasons behind that are similar though, the global handler might no longer exist due to the php engine shutting the page down).
If you're handling sensitive data and you don't want exceptions logging details such as variable contents when you throw them, you may find yourself frustratedly looking for the bits and pieces that make up a normal stack trace output, so you can retain its legibility but just alter a few things. In that case, this may help you:

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)