文档章节

PHP中register_shutdown_function函数

Ocean_K
 Ocean_K
发布于 04/04 20:01
字数 1847
阅读 8
收藏 2
PHP

1. 函数说明

定义:该函数是来注册一个会在PHP中止时执行的函数

参数说明:

void register_shutdown_function ( callable $callback [, mixed $parameter [, mixed $... ]] )

注册一个 callback ,它会在脚本执行完成或者 exit() 后被调用。

callback:待注册的中止回调

parameter:可以通过传入额外的参数来将参数传给中止函数

2. PHP中止的情况

PHP中止的情况有三种:

  • 执行完成
  • exit/die导致的中止
  • 发生致命错误中止

a. 第一种情况,执行完成

<?php

function test()
{
	echo '这个是中止方法test的输出';
}

register_shutdown_function('test'); 

echo 'before' . PHP_EOL;

运行:

before

这个是中止方法test的输出

注意:输出的顺序,等执行完成了之后才会去执行register_shutdown_function的中止方法test

b. 第二种情况,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方法导致提前中止。

c. 第三种情况,发送致命错误中止

<?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也是没有输出,致命错误导致提前中止了。

3. 参数

第一个参数支持以数组的形式来调用类中的方法,第二个以及后面的参数都是可以当做额外的参数传给中止方法。

<?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

 */

4. 同时调用多个

可以多次调用 register_shutdown_function,这些被注册的回调会按照他们注册时的顺序被依次调用。

不过注意的是,如果在第一个注册的中止方法里面调用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不会输出

 */

5. 用处

该函数的作用:

析构函数:在PHP4的时候,由于类不支持析构函数,所以这个函数经常用来模拟实现析构函数

致命错误的处理:使用该函数可以用来捕获致命错误并且在发生致命错误后恢复流程处理

代码如下:

 

<?php

/**

 * register_shutdown_function,注册一个会在php中止时执行的函数,
   中止的情况包括发生致命错误、die之后、exit之后、执行完成之后都会调用register_shutdown_function里面的函数 

 * Created by PhpStorm.

 * User: Administrator

 */

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

这样的话,PHP7中使用Throwable来捕获的话比使用register_shutdown_function这个函数来得更方便,也更推荐Throwable。

注意:Error类也是可以捕获到致命错误,不过Error只能捕获致命错误,不能捕获异常Exception,而Throwable是可以捕获到错误和异常的,所以更推荐。

6.巧用register_shutdown_function判断php程序是否执行完

还有一种应用场景就是:要做一个消费队列,因为某条有问题的数据导致致命错误,如果这条数据不处理掉,那么整个队列都会导致瘫痪的状态,这样可以用以下方法来解决。即:如果捕获到有问题的数据导致错误,则在回调函数中将这条数据处理掉就可以了。

php范例参考与解析:

<?php

register_shutdown_function('myFun'); //放到最上面,不然如果下面有致命错误,就不会调用myFun了。

$execDone = false; //程序是否成功执行完(默认为false)

/**
********************* 业务逻辑区*************************
*/

$tas = 3;

if($tas == 3) {
	new daixiaorui();
}

/**
********************* 业务逻辑结束*************************
*/

$execDone = true; //由于程序由上至下执行,因此当执行到此后,则证明逻辑没有出现致命的错误。

function myFun() {
	global $execDone;

	if($execDone === false) {
		file_put_contents("E:/myMsg.txt", date("Y-m-d H:i:s")."---error: 程序执行出错。\r\n", FILE_APPEND);
		/******** 以下可以做一些处理 ********/
	}
}

总结

register_shutdown_function这个函数主要是用在处理致命错误的后续处理上(PHP7更推荐使用Throwable来处理致命错误),不过缺点也很明显,只能处理致命错误Fatal error,其他的错误包括最高错误Parse error也是没办法处理的。

本文转载自:http://blog.csdn.net/jiandanokok/article/details/75193688

Ocean_K
粉丝 19
博文 104
码字总数 40133
作品 0
昌平
程序员
私信 提问
PHP register_shutdown_function

PHP registershutdownfunction 脚本时常死掉,而且并不总是那么好看. 我们可不想给用户显示一个致命错误,又或者一个空白页(在displayerrors设为off的情况下) . PHP中有一个叫做 registershut...

SibylY
2016/12/15
6
0
register_shutdown_function 函数详解

registershutdownfunction 函数详解 php开发测试及线上的时候可以根据不同情况设定错误和异常处理需要用到有 设定错误和异常处理三函数 1 2 3 下面讲一下registershutdownfunction() 函数. 功...

李佳顺
06/03
0
0
PHP中处理函数的函数(Function Handling Functions)

calluserfuncarray — 让参数以数组的形式调用一个函数 calluserfunc — 调用一个存在的函数 createfunction — 建立一个函数 funcgetarg — 获取函数中某个参数的值 funcgetargs — 获取函数...

酸奶喝不完
2012/09/11
0
0
PHP使用register_shutdown_function注册中断处理函数

php中registershutdownfunction用来注册一个当程序意外终止或者中断后被调用的函数。 <?phpfunction handleShutDown() { if($fp = fopen('/usr/webroot/log.txt',"wa"))   { fwrite($fp, ......

IamOkay
2014/10/27
0
0
利用php的register_shutdown_function来记录php的输出日志

最近在做的一个项目..由于全是通过远程http请求来调用php的接口程序.. 接收到的参数和返回的内容对开发人员来说都是未知不可见的.. 虽然可以通过直接在脚本中模拟请求..但由于实际环境复杂的...

酒逍遥
2012/09/14
0
1

没有更多内容

加载失败,请刷新页面

加载更多

重磅!容器集群监控利器 阿里云Prometheus 正式免费公测

Prometheus 作为容器生态下集群监控的首选方案,是一套开源的系统监控报警框架。它启发于 Google 的 borgmon 监控系统,并于 2015 年正式发布。2016 年,Prometheus 正式加入 Cloud Native C...

zhaowei121
24分钟前
2
0
Windows线程优先级

参考原文:https://www.cnblogs.com/forlina/archive/2011/08/10/2133438.html

极客行
27分钟前
2
0
聊聊前后端分离接口规范

1. 前言 随着互联网的高速发展,前端页面的展示、交互体验越来越灵活、炫丽,响应体验也要求越来越高,后端服务的高并发、高可用、高性能、高扩展等特性的要求也愈加苛刻,从而导致前后端研发...

Java面经
30分钟前
2
0
go监控方案(7) -- 实现

metrics 客户端 数据采集使用go-metrics 传输使用UDP, 仿StatsD上传采集数据, InfluxDB进行数据存储, Grafana进行展示。 实现github 地址 https://github.com/solate/metrics 该地址有已经改...

solate
34分钟前
3
0
企业微信付款到零钱

企业微信付款到零钱,提示证书不存在,可能原因如下: 1. apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定

whatwhowhy
35分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部