这篇文章主要给大家介绍了关于PHP中register_shutdown_function函数的基础介绍与用法的相关资料,需要的朋友可以参考。
前言
最近在看《PHP核心技术与最佳实践》,里面有使用到一个函数,register_shutdown_function,由于之前没有用过该函数,就去查了一下资料,就觉得是个很实用的函数,所以这里写一下这个函数的用法。下面话不多说了,来一起看看详细的介绍吧。
1. 函数说明
定义:该函数是来注册一个会在PHP中止时执行的函数
参数说明:
1 | void register_shutdown_function ( callable $callback [, mixed $parameter [, mixed $... ]] )
|
Copy after login
注册一个 callback ,它会在脚本执行完成或者 exit() 后被调用。
callback:待注册的中止回调
parameter:可以通过传入额外的参数来将参数传给中止函数
2. PHP中止的情况
PHP中止的情况有三种:
执行完成
exit/die导致的中止
发生致命错误中止
a. 第一种情况,执行完成
1 2 3 4 5 6 7 8 9 | <?php
function test()
{
echo '这个是中止方法test的输出';
}
register_shutdown_function('test');
echo 'before' . PHP_EOL;
|
Copy after login
运行:
注意:输出的顺序,等执行完成了之后才会去执行register_shutdown_function的中止方法test
b. 第二种情况,exit/die导致的中止
1 2 3 4 5 6 7 8 9 10 11 | <?php
function test()
{
echo '这个是中止方法test的输出';
}
register_shutdown_function('test');
echo 'before' . PHP_EOL;
exit ();
echo 'after' . PHP_EOL;
|
Copy after login
运行:
后面的after并没有输出,即exit或者是die方法导致提前中止。
c. 第三种情况,发送致命错误中止
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php
function test()
{
echo '这个是中止方法test的输出';
}
register_shutdown_function('test');
echo 'before' . PHP_EOL;
$a = new a();
echo 'after' . PHP_EOL;
|
Copy after login
运行:
1 2 3 4 5 6 7 8 9 10 | 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的输出
|
Copy after login
后面的after也是没有输出,致命错误导致提前中止了。
3. 参数
第一个参数支持以数组的形式来调用类中的方法,第二个以及后面的参数都是可以当做额外的参数传给中止方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php
class Shutdown
{
public function stop()
{
echo "这个是stop方法的输出" ;
}
}
register_shutdown_function([ new Shutdown(), 'stop']);
$a = new a();
echo '必须终止';
|
Copy after login
也可以在类中执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?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;
|
Copy after login
4. 同时调用多个
可以多次调用 register_shutdown_function,这些被注册的回调会按照他们注册时的顺序被依次调用。
不过注意的是,如果在第一个注册的中止方法里面调用exit方法或者是die方法的话,那么其他注册的中止回调也不会被调用。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <?php
function f( $str ) {
echo $str . PHP_EOL;
}
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;
|
Copy after login
5. 用处
该函数的作用:
析构函数:在PHP4的时候,由于类不支持析构函数,所以这个函数经常用来模拟实现析构函数
致命错误的处理:使用该函数可以用来捕获致命错误并且在发生致命错误后恢复流程处理
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <?php
class Shutdown
{
public function stop()
{
echo 'Begin.' . PHP_EOL;
if (error_get_last()) {
print_r(error_get_last());
}
die ('Stop.');
}
}
register_shutdown_function([ new Shutdown(), 'stop']);
$a = new a();
echo '必须终止';
|
Copy after login
运行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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.
|
Copy after login
注意:PHP7中新增了Throwable异常类,这个类可以捕获致命错误,即可以使用try...catch(Throwable $e)来捕获致命错误,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 | <?php
try {
$a = new a();
echo ' end ';
} catch (Throwable $e ) {
print_r( $e );
echo $e ->getMessage();
}
|
Copy after login
运行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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
|
Copy after login
这样的话,PHP7中使用Throwable来捕获的话比使用register_shutdown_function这个函数来得更方便,也更推荐Throwable。
注意:Error类也是可以捕获到致命错误,不过Error只能捕获致命错误,不能捕获异常Exception,而Throwable是可以捕获到错误和异常的,所以更推荐。
6.巧用register_shutdown_function判断php程序是否执行完
还有一种应用场景就是:要做一个消费队列,因为某条有问题的数据导致致命错误,如果这条数据不处理掉,那么整个队列都会导致瘫痪的状态,这样可以用以下方法来解决。即:如果捕获到有问题的数据导致错误,则在回调函数中将这条数据处理掉就可以了。
php范例参考与解析:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <?php
register_shutdown_function('myFun');
$execDone = 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);
}
}
|
Copy after login
总结
register_shutdown_function这个函数主要是用在处理致命错误的后续处理上(PHP7更推荐使用Throwable来处理致命错误),不过缺点也很明显,只能处理致命错误Fatal error,其他的错误包括最高错误Parse error也是没办法处理的。
相关推荐:
Analysis of PHP register_shutdown_function function
In-depth understanding of register_shutdown_function function in php
Usage of register_shutdown_function function in php
The above is the detailed content of Introduction and usage of register_shutdown_function function in PHP (case). For more information, please follow other related articles on the PHP Chinese website!