PHP 注册错误和异常处理机制
注册错误和异常处理机制有三个PHP函数需要学习
1. register_shutdown_function('Bootstrap\Library\Frame::fatalError');
2. set_error_handler('Bootstrap\Library\Frame::appError');
3. set_exception_handler('Bootstrap\Library\Frame::appException');
1.register_shutdown_function
定义:该函数是来注册一个会在PHP中止时执行的函数
参数说明:
void register_shutdown_function ( callable $callback [, mixed $parameter [, mixed $... ]] )
注册一个 callback ,它会在脚本执行完成或者 exit() 后被调用。
callback:待注册的中止回调
parameter:可以通过传入额外的参数来将参数传给中止函数
PHP终止情况有三种
执行完成
<?php
function test()
{
echo '这个是中止方法test的输出';
} register_shutdown_function('test'); echo 'before' . PHP_EOL; // => before
// => 这个是中止方法test的输出
注意输出的顺序,等执行完成了之后才会去执行register_shutdown_function的中止方法test
exit/die导致的中止
<?php
function test()
{
echo '这个是中止方法test的输出';
} register_shutdown_function('test'); echo 'before' . PHP_EOL;
exit();
echo 'after' . PHP_EOL; // => before
// => 这个是中止方法test的输出
后面的after并没有输出,即exit或者是die方法导致提前中止。
发生致命错误中止
<?php
function test()
{
echo '这个是中止方法test的输出';
} register_shutdown_function('test'); echo 'before' . PHP_EOL; // 这里会发生致命错误
$a = new a(); echo 'after' . PHP_EOL; // => before
// => Fatal error: Uncaught Error: Class 'a' not found in D:\laragon\www\php_book\test.php on line 12
// => Error: Class 'a' not found in D:\laragon\www\php_book\test.php on line 12
// => Call Stack:
// => 0.0020 360760 1. {main}() D:\laragon\www\php_book\test.php:0
// => 这个是中止方法test的输出
后面的after也是没有输出,致命错误导致提前中止了。
参数:第一个参数支持以数组的形式来调用类中的方法,第二个以及后面的参数都是可以当做额外的参数传给中止方法。
<?php class Shutdown
{
public function stop()
{
echo "这个是stop方法的输出";
}
} // 当PHP终止的时候(执行完成或者是遇到致命错误中止的时候)会调用new Shutdown的stop方法
register_shutdown_function([new Shutdown(), 'stop']); // 将因为致命错误而中止
$a = new a(); // 这一句并没有执行,也没有输出
echo '必须终止';
也可以在类中执行:
<?php
class TestDemo {
public function __construct()
{
register_shutdown_function([$this, "f"], "hello");
}
public function f($str)
{
echo "class TestDemo->f():" . $str;
}
}
$demo = new TestDemo();
echo 'before' . PHP_EOL;
/**
运行:
before
class TestDemo->f():hello
*/
不过注意的是,如果在第一个注册的中止方法里面调用exit方法或者是die方法的话,那么其他注册的中止回调也不会被调用。
<?php
/**
* 可以多次调用 register_shutdown_function,这些被注册的回调会按照他们注册时的顺序被依次调用。
* 注意:如果你在f方法(第一个注册的方法)里面调用exit方法或者是die方法的话,那么其他注册的中止回调也不会被调用
*/ /**
* @param $str
*/
function f($str) {
echo $str . PHP_EOL; // 如果下面调用exit方法或者是die方法的话,其他注册的中止回调不会被调用
// exit();
} // 注册第一个中止回调f方法
register_shutdown_function("f", "hello"); class TestDemo {
public function __construct()
{
register_shutdown_function([$this, "f"], "hello");
} public function f($str)
{
echo "class TestDemo->f():" . $str;
}
} $demo = new TestDemo();
echo 'before' . PHP_EOL; /**
运行:
before
hello
class TestDemo->f():hello 注意:如果f方法里面调用了exit或者是die的话,那么最后的class TestDemo->f():hello不会输出
*/
- 析构函数:在PHP4的时候,由于类不支持析构函数,所以这个函数经常用来模拟实现析构函数
- 致命错误的处理:使用该函数可以用来捕获致命错误并且在发生致命错误后恢复流程处理
代码如下:
<?php
/**
* register_shutdown_function,注册一个会在php中止时执行的函数,中止的情况包括发生致命错误、die之后、exit之后、执行完成之后都会调用register_shutdown_function里面的函数
* Created by PhpStorm.
* User: Administrator
* Date: 2017/7/15
* Time: 17:41
*/ class Shutdown
{
public function stop()
{
echo 'Begin.' . PHP_EOL;
// 如果有发生错误(所有的错误,包括致命和非致命)的话,获取最后发生的错误
if (error_get_last()) {
print_r(error_get_last());
} // ToDo:发生致命错误后恢复流程处理 // 中止后面的所有处理
die('Stop.');
}
} // 当PHP终止的时候(执行完成或者是遇到致命错误中止的时候)会调用new Shutdown的stop方法
register_shutdown_function([new Shutdown(), 'stop']); // 将因为致命错误而中止
$a = new a(); // 这一句并没有执行,也没有输出
echo '必须终止';
Fatal error: Uncaught Error: Class 'a' not found in D:\laragon\www\php_book\1_23_register_shutdown.php on line 31 Error: Class 'a' not found in D:\laragon\www\php_book\1_23_register_shutdown.php on line 31 Call Stack:
0.0060 362712 1. {main}() D:\laragon\www\php_book\1_23_register_shutdown.php:0 Begin.
Array
(
[type] => 1
[message] => Uncaught Error: Class 'a' not found in D:\laragon\www\php_book\1_23_register_shutdown.php:31
Stack trace:
#0 {main}
thrown
[file] => D:\laragon\www\php_book\1_23_register_shutdown.php
[line] => 31
)
Stop.
注意:PHP7中新增了Throwable异常类,这个类可以捕获致命错误,即可以使用try...catch(Throwable $e)来捕获致命错误,代码如下:
<?php
try {
// 将因为致命错误而中止
$a = new a();
// 这一句并没有执行,也没有输出
echo 'end';
} catch (Throwable $e) {
print_r($e);
echo $e->getMessage();
}
运行:
Error Object
(
[message:protected] => Class 'a' not found
[string:Error:private] =>
[code:protected] => 0
[file:protected] => C:\laragon\www\php_book\throwable.php
[line:protected] => 5
[trace:Error:private] => Array
(
) [previous:Error:private] =>
[xdebug_message] =>
Error: Class 'a' not found in C:\laragon\www\php_book\throwable.php on line 5 Call Stack:
0.0000 349856 1. {main}() C:\laragon\www\php_book\throwable.php:0 )
Class 'a' not found
2.set_error_handler
通过 set_error_handler() 函数设置用户自定义的错误处理程序,然后触发错误(通过 trigger_error()):
<?php
// 用户定义的错误处理函数
function myErrorHandler($errno, $errstr, $errfile, $errline) {
echo "<b>Custom error:</b> [$errno] $errstr<br>";
echo " Error on line $errline in $errfile<br>";
} // 设置用户定义的错误处理函数
set_error_handler("myErrorHandler"); $test=2; // 触发错误
if ($test>1) {
trigger_error("A custom error has been triggered");
}
?>
以上代码的输出类似这样:
Custom error: [1024] A custom error has been triggered
Error on line 14 in C:\webfolder\test.php
定义和用法
set_error_handler() 函数设置用户定义的错误处理函数。
注释:如果使用该函数,会绕过标准 PHP 错误处理程序,同时如果必要,用户定义错误程序通过 die() 终止脚本。
注释:如果错误发生在脚本执行之前(比如文件上传时),将不会调用自定义的错误处理程序因为它尚未在那时注册。
语法
set_error_handler(errorhandler,E_ALL|E_STRICT);
| 参数 | 描述 |
|---|---|
| errorhandler | 必需。规定用户错误处理函数的名称。 |
| E_ALL|E_STRICT | 可选。规定显示何种错误报告级别的用户定义错误。默认是 "E_ALL"。 |
技术细节
| 返回值: | 包含之前定义的错误处理程序的字符串。 |
|---|---|
| PHP 版本: | 4.0.1+ |
| PHP 更新日志: |
PHP 5.5:参数 errorhandler 现在接受 NULL PHP 5.2: 错误处理程序必须返回 FALSE 来显示 $php_errormsg。 |
3.set_exception_handler
设置用户定义的异常处理函数:
<?php
// 用户定义的异常处理函数
function myException($exception) {
echo "<b>Exception:</b> ", $exception->getMessage();
} // 设置用户定义的异常处理函数
set_exception_handler("myException"); // 抛出异常
throw new Exception("Uncaught exception occurred!");
?>
以上代码的输出类似这样:
Exception: Uncaught exception occurred!
定义和用法
set_exception_handler() 函数设置用户定义的异常处理函数。
脚本会在此异常处理程序被调用后停止执行。
语法
set_exception_handler(exceptionhandler);
| 参数 | 描述 |
|---|---|
| exceptionhandler |
必需。规定当一个未捕获的异常发生时所调用函数的名称。 注释:也可以传递一个 NULL 值用于重置异常处理函数为默认值。 |
技术细节
| 返回值: |
返回包含之前定义的异常处理程序的名称的字符串,或者在错误时返回 NULL。 如果之前没有定义一个错误处理程序,也会返回 NULL。 如果参数使用了 NULL,重置处理程序为默认状态,并且会返回一个 TRUE。 |
|---|---|
| PHP 版本: | 5.0+ |
| PHP 更新日志: |
PHP 7.0.0:传递到 exception_handler 中的参数类型从 Exception 更改为 Throwable。 PHP 5.5:之前,如果传递 NULL,该函数返回 TRUE。从 PHP 5.5 起返回之前的处理程序。 |
PHP 注册错误和异常处理机制的更多相关文章
- ThinkPHP5.0源码学习之注册错误和异常处理机制
在base.php文件中,用一句代码\think\Error::register();实现错误和异常处理机制的注册. // 注册错误和异常处理机制 \think\Error::register(); ...
- 【Go语言】错误与异常处理机制
①error接口 Go语言中的error类型实际上是抽象了Error()方法的error接口 type error interface { Error() string } Go语言使用该接口进行标准 ...
- php5和php7的异常处理机制 ----thinkphp5 异常处理的分析
1.php异常和错误 在其他语言中,异常和错误是有区别的,但是PHP,遇见自身错误时,会触发一个错误,而不是跑出异常.并且,php大部分情况,都会触发错误,终止程序执行,在php5中,try catc ...
- php错误处理和php异常处理机制
php错误处理 当我们开发程序时,有时候程序出现了问题,我们就可以用以下几种办法找出错误. 开发阶段:开发时输出所有的错误报告,有利于我们进行程序调试 运行阶段:我们不要让程序输出任何一种错误报 ...
- 再谈PHP错误与异常处理
博客好久没有更新了,实在惭愧,最近在忙人生大事,哈哈!这段时间没有看什么新的东西,结合项目中遇到的PHP异常处理问题,我又重新梳理了之前模糊的概念,希望对大家理解PHP异常处理有所帮助. 请一定要注意 ...
- Spring Cloud微服务如何设计异常处理机制?
导读 今天和大家聊一下在采用Spring Cloud进行微服务架构设计时,微服务之间调用时异常处理机制应该如何设计的问题.我们知道在进行微服务架构设计时,一个微服务一般来说不可避免地会同时面向内部和外 ...
- 2018/05/02 PHP 之错误与异常处理
在学习中,越学习越觉得自己基础薄弱. 在平常工作中,对于某些错误处理感觉不知道怎么下手,于是决定重新再整理一下. 强烈推荐这篇文章,真的感觉学习到了很多. 部分引用::再谈PHP错误与异常处理 -- ...
- SpringMVC异常处理机制
SpringMVC异常处理机制 springMVC会将所有在doDispatch方法中的异常捕获,然后处理.无法处理的异常会抛出给容器处理. 在doDispatch()中调用processDispat ...
- C++ 异常处理机制的实现
http://blog.jobbole.com/103925/ 本文深入讨论了VC++编译器异常处理的实现机制.附件源代码包含了一个VC++的异常处理库. 下载源代码 – 19 Kb 介绍 相对于传统 ...
随机推荐
- C#打印标签
一个复杂的标签包括一个复杂的表格样式和二维码.条形码等内容.所以如果直接绘制的方式将会非常的麻烦,所以采用使用的方案是使用模板的方式:1.使用Excel创建出想要的模板的样式.2.对模板中的动态内容进 ...
- python爬取并批量下载图片
import requests from lxml import etree url='http://desk.zol.com.cn/meinv/' add1='.html' urls=[] i = ...
- bootstrap modal 弹出其他页面
此文是可以的,是复制的然后粘贴 1.不使用js 方式 1.1 按钮 <a class=" btn default" href="ui_modals_ajax_sam ...
- easyui datagrid 去掉外边框及行与行之间的横线标题字体
这是以前写的一个项目中写的东西,为了让datagrid样式好看,所有做的这个处理: 今天同事又问到于是记录下来 $('#id').datagrid({ width: '99%', height: 15 ...
- 初级ai思维导图,基础人工智能设计图
2017年2月8日09:35:46 仅供代码和逻辑设计图纸,只提供一个参考设计,后面可能会更新具体实施说明
- Luogu 3369 / BZOJ 3224 - 普通平衡树 - [替罪羊树]
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3224 https://www.luogu.org/problemnew/show/P3 ...
- [No0000169]Potplayer倍速播放快捷键修改速率步长
右键-播放-播放设置-速度调整单位改成0.5,即可一次加速到1.5
- [No000011D].NETCORE1/19-.NET Core 指南
.NET Core 是一个通用开发平台,由 Microsoft 和 GitHub 上的 .NET 社区共同维护.跨平台的,支持 Windows.macOS 和 Linux,并且可用于设备.云和嵌入式/ ...
- [No0000FB]C# 命名空间(Namespace)
命名空间的设计目的是提供一种让一组名称与其他名称分隔开的方式.在一个命名空间中声明的类的名称与另一个命名空间中声明的相同的类的名称不冲突. 定义命名空间 命名空间的定义是以关键字 namespace ...
- NLP去特殊字符
在自然语言处理中,我们有时对文本进行处理,需要去除一些特殊符号,保留中文,这是在预处理过程中常用到的.分享给你,希望对你有帮助! import re def delete_sysbol(line): ...