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 介绍 相对于传统 ...
随机推荐
- linux命令学习(4):cd命令
Linux cd 命令可以说是Linux中最基本的命令语句,其他的命令语句要进行操作,都是建立在使用 cd 命令上的.所以,学习Linux 常用命令,首先就要学好 cd 命令的使用方法技巧. 1. 命 ...
- js dom 观察者属性 MutationObserver
MDN上说的很清楚 MutationObserver给开发者们提供了一种能在某个范围内的DOM树发生变化时作出适当反应的能力.该API设计用来替换掉在DOM3事件规范中引入的Mutation事件 co ...
- asp.net C#绘制太极图
成品图: html页面: 注意设置 ContentType="Image/Jpeg" <%@ Page Language="C#" AutoEventWi ...
- MPD软件工作坊上海站本周末在上海举行
本周末(5月26日至27日)由麦思博(msup)主办的第39届MPD软件工作坊即将在上海虹桥会议中心举行.本届MPD将继续围绕软件研发领域,邀请了21位技术大咖,从产品运营.团队管理.架构技术.自动化 ...
- ThinkPad X1 Carbon 2018 Windows 10无法关机的问题
最近两天在工作中很多同事都遇到了自己的X1电脑关机时自动重启的现象,这个问题让我在知乎.微软支持.国外各种科技论坛找到了很多类似的症状. 但是针对同事们遇到的问题,解决方案异常的简单:就是下载联想驱动 ...
- DHCP协议和PXE
在学习IP地址基本概念之后,需要了解到如果需要和其他机器通讯,我们就需要一个通讯地址,我们需要给网卡配置一个地址. 如何配置 IP 地址? 可以用命令行自己配置一个地址.可以使用 ifconfig,也 ...
- linux:基本概念和操作
1. 终端 Linux 默认提供了 6 个纯命令行界面的 “terminal”(准确的说这里应该是 6 个 virtual consoles)来让用户登录,在物理机系统上你可以通过使用[Ctrl]+[ ...
- 确界原理 supremum and infimum principle 戴德金定理 Dedekind theorem
确界原理 supremum and infimum principle 戴德金定理 Dedekind theorem http://www.math.ubc.ca/~cass/courses/m ...
- Page8:对偶原理以及结构分解[Linear System Theory]
内容包含状态转移矩阵的对偶性.方块图的对偶性.时序的对偶性以及对偶性原理,能控能观标准型及其结构分解
- [skill] vim 操作多个window
前言: 分辨率越来越高,屏幕越来越大,行最长80不变,屏幕利用空白越来越大. 开多个window吧! 开window的命令: 平行开一个window:split <//path/file> ...